home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 025a / cdb120.zip / CDB.TXT next >
Text File  |  1991-05-20  |  96KB  |  3,067 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.                                       CDB
  15.  
  16.  
  17.                          Copyright (C) 1991 by Daytris
  18.                                All rights reserved
  19.  
  20.  
  21.  
  22.                              Revised: May 20th, 1991
  23.  
  24.  
  25. INTRODUCTION
  26.  
  27.  
  28. Overview
  29.  
  30.         CDB is a sophisticated database toolkit for MS-DOS and UNIX
  31.         developers.  CDB includes the following features:
  32.  
  33.             - Quick data access through a sophisticated multi-key ISAM
  34.               implementation.
  35.  
  36.             - Multiple data models.  Both relational and network data
  37.               models are implemented in CDB.  The network model gives the
  38.               developer the ability to create relationships between
  39.               records without storing unique keys in those records.
  40.  
  41.             - Data Definition Language (DDL) for defining database layouts.
  42.               The DDL is compiled into a binary format which is used by the
  43.               database server as a roadmap.  Using this concept, a
  44.               developer can define and re-define a database with minimal
  45.               effort and absolutely no code changes.  The DDL is patterned
  46.               after C for ease of programming.
  47.  
  48.             - Over 30 predefined database function calls for complete
  49.               control of the database.
  50.  
  51.             - Portability.  CDB is written entirely in C for portability
  52.               and source code is included with your purchase.  A version
  53.               of CDB is also available for the MS-Windows platform.
  54.               Contact the developers for more information about this
  55.               product.
  56.  
  57.             - C++ compatibility.  The library is callable from both C and
  58.               C++.
  59.  
  60.             - Automatic re-use of deleted database space.  There is no need
  61.               for database reorganization.  Deleted space is automatically
  62.               reused by CDB.
  63.  
  64.             - Low overhead.  The CDB database engine requires an extremely
  65.               small amount of memory to operate.
  66.  
  67.             - Royalty-free distribution rights.  Whether you have one
  68.               customer or thousands, you pay for CDB just once for each
  69.               environment that you are using.
  70.  
  71.  
  72. Obtaining CDB
  73.  
  74.         Refer to the document included in this release, ORDER.TXT, to order
  75.         CDB.  Your purchase will include CDB libraries, utilities, royalty-
  76.         free use of library functions, full library and utility source code
  77.         and make files.  A printed manual will also be included.
  78.  
  79.  
  80. Future Enhancements
  81.  
  82.         Listed below are some of the enhancements planned for CDB.  Any
  83.         suggestions would also be greatly appreciated.
  84.  
  85.         - Multi-user database access.  Networks and/or protocols to be
  86.           supported are currently undefined.
  87.  
  88.         - Performance enhancements.
  89.  
  90.  
  91. Contacting the Developers
  92.  
  93.         CDB was developed solely by Daytris.  If you have a question about
  94.         the product or any suggestions please contact us at the phone
  95.         number listed below.  Or if you prefer, you can send us electronic
  96.         mail on any of the information services listed.
  97.  
  98.         Daytris
  99.         81 Bright Street, Suite 1E
  100.         Jersey City, NJ  07302
  101.         201-200-0018
  102.  
  103.         CompuServe:    72500,1426
  104.         BIX:            daytris
  105.         GEnie:            t.fearn
  106.  
  107.  
  108. GETTING STARTED 
  109.  
  110.  
  111. Unpacking
  112.  
  113.         CDB is distributed in self-extracting ZIP files.  When you first
  114.         unpack your software, you may want to verify that you have a
  115.         complete set.  If you have the Test Drive version, you should have
  116.         the files included in CDB.EXE.  If you have purchased CDB, you
  117.         should have the files included in both CDB.EXE and CDBSRC.EXE.
  118.         The contents of each are listed below.
  119.  
  120.         CDB.EXE
  121.  
  122.                 File Name    Description
  123.                 ---------       -----------
  124.  
  125.                 CDB.TXT            This document.
  126.                 ORDER.TXT    Order form for CDB.
  127.                 REGISTER.TXT    Registration form for CDB.
  128.                 README.TXT    Latest CDB info.
  129.                 UPDATES.TXT    History of updates made to CDB.
  130.                 MSCCDBL.LIB    CDB library.  Microsoft C large model.
  131.                 TCCDBL.LIB    CDB library.  Turbo C large model.
  132.                 DBDLIST.EXE    Database Definition (DBD) file display
  133.                                 utility.
  134.                 DDLP.EXE    Database Definition Language Parser.
  135.                 TEST.C      TEST do nothing program.
  136.                 TEST.DDL    TEST Data Definition Language File.
  137.                 DBMGR.H         CDB header file.
  138.                 MSCTEST.MAK    Make file for TEST (Microsoft C).
  139.                                 Microsoft NMAKE and UNIX make compatible.
  140.                 TCTEST.MAK    Make file for TEST (Turbo C).  Microsoft
  141.                                 NMAKE and UNIX make compatible.
  142.  
  143.  
  144.         CDBSRC.EXE
  145.  
  146.                 File Name    Description
  147.                 ---------       -----------
  148.  
  149.                 LICENSE.TXT    Daytris software license agreement.
  150.                 MSCLIB.MAK    Library make file (Microsoft C).
  151.                                 Microsoft NMAKE and UNIX make compatible.
  152.                 TCLIB.MAK    Library make file (Turbo C).  Microsoft
  153.                                 NMAKE and UNIX make compatible.
  154.                 DBADD.C            Library source file.
  155.                 DBUPD.C            .
  156.                 DBDEL.C            .
  157.                 DBFIND.C    .
  158.                 DBGET.C            .
  159.                 DBCURR.C    .
  160.                 DBFILE.C    .
  161.                 DBMGR.C            .
  162.                 DBPAGE.C    .
  163.                 DBSLOT.C    .
  164.                 DBTALK.C    .
  165.                 DBFUNCS.C    .
  166.                 DBMGR.H            CDB header file.
  167.                 DBXTRN.H    External definitions header file.
  168.                 STDINC.H    Header file that includes other header
  169.                                 files used in CDB.
  170.                 DDLP.MAK    Make file for DDLP.  Microsoft NMAKE and
  171.                                 UNIX make compatible.
  172.                 MAIN.C            DDLP source file.
  173.                 DDLP.C            .
  174.                 PARSE.C            .
  175.                 ERROR.C            .
  176.                 DDLP.H            DDLP header file.
  177.                 DBDLIST.MAK    Make file for DBDLIST.  Microsoft NMAKE and
  178.                                 UNIX make compatible.
  179.                 DBDLIST.C    DBDLIST source file.
  180.  
  181.  
  182. THE NETWORK DATABASE MODEL
  183.  
  184.  
  185. Introduction
  186.  
  187.         CDB provides both relational and network model features.  The use
  188.         of both models in a data design can greatly increase the
  189.         performance of your database.  For those of you who are already
  190.         familiar with the relational database concepts, you will find the
  191.         network model implementation very refreshing.  For those of you
  192.         who aren't familiar with the relational model, a very brief
  193.         description of relational concepts follows.
  194.  
  195.  
  196. The Relational Model
  197.  
  198.         In a relational database, data is stored in a series of tables.
  199.         Each table consists of a number of columns, which identify a
  200.         particular type of data, and rows, which correspond to a particular
  201.         record in the table.
  202.  
  203.         Individual records can be retrieved using the key fields defined
  204.         for the table.  If the developer has the desire to make an
  205.         association between two tables, unique key fields must be defined
  206.         in both records and unique data must be stored for retrieval to 
  207.         take place.
  208.  
  209.  
  210. What is the Network Model?
  211.  
  212.         This model allows you to define relationships between records
  213.         through constructs called sets.  A set defines a one-to-many
  214.         relationship between two tables.
  215.  
  216.         In a relational model, records can only be related (connected)
  217.         by storing unique keys in both tables.  This method creates
  218.         additional unwanted overhead.  Duplicate data is stored in both
  219.         records and duplicate indexes must be managed.
  220.  
  221.         Using the network model, records are connected by directly storing
  222.         data pointers inside the record.  Where the relational model
  223.         requires multiple disk accesses to locate a related record, the
  224.         network model allows the record to be located in a single disk
  225.         access.  Disk space is also saved when sets are used because no
  226.         index is required.
  227.  
  228.         Another advantage of using the network model is the flexibility
  229.         of owner/member relationships.  A record may own multiple record
  230.         types.  A record may also be owned by multiple owner records.  An
  231.         example of this would be a 'client' record owning 'invoice'
  232.         records and also owning 'address' records.  In turn, an 'invoice'
  233.         could also own 'address' records, perhaps a shipping and billing
  234.         address.  This kind of flexibility gives the developer the power
  235.         to define complex data relationships with relative ease.
  236.  
  237.  
  238. THE DATA DEFINITION LANGUAGE
  239.  
  240. Introduction
  241.  
  242.         The Data Definition Language is used for defining a database model.
  243.         The language is basically a superset of C structure definitions.
  244.         If you are familiar with defining C structures, the DDL should be
  245.         very easy to pick up on.
  246.  
  247.         The DbOpen function call loads a binary image of a DDL file.  The
  248.         binary image is created by compiling the DDL file into a DBD
  249.         (Database Definition) format.  A DDL compiler is included with this
  250.         release, DDLP.EXE (Data Definition Language Parser).
  251.  
  252.  
  253. An Example:
  254.  
  255.         /* sampledb.ddl */
  256.  
  257.         prefix ABC;
  258.  
  259.         struct client
  260.             {
  261.             connect    address key street;
  262.             key long    clientnbr;
  263.             key char    name[31];
  264.             char    description[61];
  265.             double    balance;
  266.             };
  267.  
  268.         struct address
  269.             {
  270.             char    street[31];
  271.             char    city[21];
  272.             char    sate[3];
  273.             key char    zip[11];
  274.             key char    telephone[13];
  275.             char    fax[13];
  276.             };
  277.  
  278.         struct setup
  279.             {
  280.             key long    nextclientnbr;
  281.             };
  282.  
  283.  
  284.         Notice the close resemblence to C structure definitions.  The only
  285.         differences are the prefix, connect, and key words.
  286.  
  287.  
  288.  
  289.         prefix
  290.  
  291.         The prefix is used internally by the database library when a new
  292.         database file must be created.  In the SAMPLEDB.DDL shown above,
  293.         the prefix is "ABC".  By defining the prefix as "ABC", we are
  294.         telling the library to use "ABC" as the first 3 characters of any
  295.         file that is created for the SAMPLEDB database.
  296.  
  297.         The prefix can be from 1 to 4 characters in length.  If a prefix is
  298.         not defined, a default prefix, "TEST", is used.
  299.  
  300.         For more information about the CDB database file naming
  301.         conventions, refer to the 'Database File Names' section in this
  302.         manual.
  303.  
  304.  
  305.         connect
  306.  
  307.         When using the connect keyword, you are taking advantage of the
  308.         network database model implementation of CDB.  Network model
  309.         concepts can greatly increase the performance and efficiency of
  310.         your database.
  311.  
  312.         The connect keyword defines a relationship between two records.
  313.  
  314.         struct client
  315.             {
  316.             connect    address key street;
  317.                 .
  318.                 .
  319.             };
  320.  
  321.         In this example, we are defining a relationship between the client
  322.         record and the address record.  The client record will be an owner
  323.         of the address record.  The address record is a member of the
  324.         client record.  For now, ignore the 'key street' part of the
  325.         connect phrase.
  326.  
  327.         By declaring this set relationship, we now have the capability to
  328.         make connections between client and address records using the
  329.         DbSet... function calls.  A client may own 0, 1 or many address
  330.         records.  Without the network model concepts that we have just
  331.         shown you, to make connections between two records would require
  332.         the storage of a unique key in each individual record.
  333.  
  334.         void Function()
  335.             {
  336.             static CLIENT client = {1000L,"Daytris","A software company",
  337.                 0.00};
  338.             static ADDRESS address = {"81 Bright Street, Suite 1E",
  339.                 "Jersey City","NJ","07302","201-200-0018",""};
  340.  
  341.             DbRecordAdd( "client", &client);
  342.             DbRecordAdd( "address", &address);
  343.             DbSetAdd( "client", "address");
  344.             }
  345.  
  346.  
  347.         The example above shows how to make a set connection between two
  348.         records by using the DbSetAdd function.  After the function call,
  349.         the client "Daytris" is the owner of 1 address record.  This
  350.         address record can be retrieved using the DbSetGetFirst call:
  351.  
  352.         DbSetGetFirst( "client", "address", &address);
  353.  
  354.  
  355.         Now lets add another address record to the set:
  356.  
  357.         void Function()
  358.             {
  359.             long key = 1000L;
  360.             static ADDRESS address = {"30 Broad Street","New York","NY",
  361.                 "10015","212-555-1212","212-555-1212"};
  362.  
  363.             /* Make client #1000 current */
  364.             DbRecordFindByKey( "client", "clientnbr", &key);
  365.  
  366.             /* Add another member */
  367.             DbRecordAdd( "address", &address);
  368.             DbSetAdd( "client", "address");
  369.             }
  370.  
  371.         The client "Daytris" now owns 2 address records.  We can use the
  372.         DbSetGetFirst, DbSetGetLast, DbSetGetNext, or DbSetGetPrev to
  373.         retrieve any of the address records in the set.
  374.  
  375.         Now lets take a look at how the sets are ordered.  If we make a
  376.         DbSetGetFirst call after adding the sets shown above, which address
  377.         record would be returned?  Lets return to our original DDL example:
  378.  
  379.         struct client
  380.             {
  381.             connect    address key street;
  382.                 .
  383.                 .
  384.             };
  385.  
  386.         Member records can be ordered two ways.  By the order in which they
  387.         are added, or by a field in the member record.  In our example, the
  388.         set order is by the street field in the address record.  Therefore,
  389.         a DbSetGetFirst( "client", "address", ...) call would return the
  390.         "30 Broad Street" address record.  If the connect address phrase
  391.         were defined without a key:
  392.  
  393.         struct client
  394.             {
  395.             connect    address;
  396.                 .
  397.                 .
  398.             };
  399.  
  400.  
  401.         the address members would be stored in the order that they were
  402.         added.  Therefore, a DbSetGetFirst( "client", "address", ...)
  403.         call would return the "81 Bright Street, Suite 1E" address because
  404.         this address was added first.
  405.  
  406.         A record can have more than one member.  A record can also be owned
  407.         by more than one owner.  To illustrate this, lets take the
  408.         SAMPLEDB.DDL and expand it to include invoicing capabilities.
  409.  
  410.         /* sampledb.ddl - with invoicing */
  411.  
  412.         prefix ABC;
  413.  
  414.         struct client
  415.             {
  416.             connect    address key street;
  417.             connect    invoice;
  418.             key long    clientnbr;
  419.             key char    name[31];
  420.             char    description[61];
  421.             double    balance;
  422.             };
  423.  
  424.         struct address
  425.             {
  426.             char    street[31];
  427.             char    city[21];
  428.             char    state[3];
  429.             key char    zip[11];
  430.             key char    telephone[13];
  431.             char    fax[13];
  432.             };
  433.  
  434.         struct invoice
  435.             {
  436.             connect     address;
  437.             connect    invoiceline;
  438.             key long    invoicenbr;
  439.             long    date;
  440.             double    totalprice;
  441.             };
  442.  
  443.         struct invoiceline
  444.             {
  445.             long    quantity;
  446.             char    description[31];
  447.             double    unitprice;
  448.             double    lineprice;
  449.             };
  450.  
  451.         struct setup
  452.             {
  453.             key long    nextclientnbr;
  454.             long    nextinvoicenbr;
  455.             };
  456.  
  457.  
  458.         In this example, a client record can own multiple address records
  459.         and multiple invoice records.  This makes sense because a client
  460.         could have more than one address, i.e. a shipping and billing
  461.         address.  The client could also have more than one invoice if more
  462.         than one order is placed.
  463.  
  464.         Also in this example, an owner/member relationship exists between
  465.         the invoice and address records.  If our invoice has both 'ship to'
  466.         and 'bill to' addresses, the shipping address could be stored as
  467.         the first member in the set and the billing address could be stored
  468.         as the next member.
  469.  
  470.         A variable number of line items could exist on an invoice.  This is
  471.         the reason for the invoiceline record and its relationship with the
  472.         invoice.  An invoice record will own its invoice lines.
  473.  
  474.         The following example illustrates how all data pertaining to a
  475.         specific invoice might be retrieved.  Note: it is suggested that
  476.         the CDB return values be taken more seriously than illustrated
  477.         below.
  478.  
  479.         typedef struct invoice INVOICE;
  480.         typedef struct invoiceline INVOICELINE
  481.         typedef struct client CLIENT;
  482.         typedef struct address ADDRESS;
  483.  
  484.  
  485.         void Function()
  486.             {
  487.             long key = 2000L;
  488.             UINT status;
  489.             INVOICE invoice;
  490.             INVOICELINE invoiceline;
  491.             CLIENT client;
  492.             ADDRESS shipaddress;
  493.             ADDRESS billaddress;
  494.  
  495.             /* Get invoice #2000 */
  496.             DbRecordGetByKey( "invoice", "invoicenbr", &invoice, &key);
  497.  
  498.             /* Get the client that owns the invoice */
  499.             DbSetGetOwner( "client", "invoice", &client);
  500.  
  501.             /* Get the 'ship to' and 'bill to' addresses */
  502.             DbSetGetFirst( "invoice", "address", &shipaddress);
  503.             DbSetGetNext( "invoice", "address", &billaddress);
  504.  
  505.             /* Retrieve all invoice lines (assuming at least 1 line) */
  506.             status = DbSetGetFirst( "invoice", "invoiceline", &invoiceline);
  507.             while( status != E_NONEXT && status != E_NOTFOUND)
  508.                 {
  509.                 /* Store the line */
  510.  
  511.                 /* Get the next line */
  512.                 status = DbSetGetNext( "invoice", "invoiceline",
  513.                         &invoiceline);
  514.                 }
  515.             }
  516.  
  517.         This example illustrates some of the capabilities that you have
  518.         with set relationships.  The possibilities are endless.
  519.  
  520.  
  521.         key
  522.  
  523.         The key word is used for defining key fields in records and key
  524.         fields to be used in set relationships.  See the connect section
  525.         directly preceding this section for more details about the key
  526.         fields in set relationships.
  527.  
  528.         Key fields are stored in ascending order in slots on pages in a
  529.         key file.  The key file is made up of a series of linked pages.
  530.  
  531.         struct client
  532.             {
  533.             connect    address key street;
  534.             key long    clientnbr;
  535.             char    name[31];
  536.             char    description[61];
  537.             double    balance;
  538.             };
  539.  
  540.  
  541.         This DDL structure definition contains only one key field,
  542.         "clientnbr".  Therefore all pages in the corresponding key file
  543.         will contain will contain slots of sorted client numbers.
  544.  
  545.         struct client
  546.             {
  547.             connect    address key street;
  548.             key long    clientnbr;
  549.             key char    name[31];
  550.             char    description[61];
  551.             double    balance;
  552.             };
  553.  
  554.         The DDL structure definition now contains two key fields,
  555.         "clientnbr" and "name".  Therefore two types of key pages will
  556.         exist in the key file for this record type.  Some pages will
  557.         contain slots of sorted client numbers and other pages will contain 
  558.         slots of sorted client names.  The data stored on the key file
  559.         pages is directly related to the number of key fields defined in
  560.         the DDL file.
  561.  
  562.         To maximize the efficiency of your database, it is suggested that
  563.         you use as few key fields as possible.  The maximum number of key
  564.         fields allowed in a record is defined as MAXKEY in DBMGR.H.  It is
  565.         currently set to 8.  See 'Modifying the Database Internals' section
  566.         for more information about MAXKEY.
  567.  
  568.         If a structure is defined without a key field, the only way to
  569.         access a record of this type is with a set relationship.  The
  570.         structure defined without a key field must be a member of another
  571.         record.
  572.  
  573.         struct client
  574.             {
  575.             connect    address key street;
  576.             key long    clientnbr;
  577.             key char    name[31];
  578.             char    description[61];
  579.             double    balance;
  580.             };
  581.  
  582.         struct address
  583.             {
  584.             char    street[31];
  585.             char    city[21];
  586.             char    state[3];
  587.             char    zip[11];
  588.             char    telephone[13];
  589.             char    fax[13];
  590.             };
  591.  
  592.         In this example, the address record contains no key fields.
  593.         Therefore, the address record cannot be accessed using any
  594.         DbRecord... function calls because these functions require a key
  595.         field as a parameter.  However, the address is a member of the
  596.         client record.  Therefore, it could be accessed with the
  597.         DbSetGet... function calls, provided a relationship exists.
  598.  
  599.  
  600. DDL Limitations
  601.  
  602.         The Data Definition Language does not currently support the
  603.         definition of structures or unions defined from within a structure.
  604.         Example:
  605.  
  606.         struct client
  607.             {
  608.             struct address addr;
  609.             key long    clientnbr;
  610.             key char    name[31];
  611.             char    description[61];
  612.             double    balance;
  613.             };
  614.  
  615.         These deficiencies will be supported in a later release of CDB.
  616.         A way to get around this problem for now is to allocate enough
  617.         space as a char field for the structure or union that could not be
  618.         included.  Example (assuming the address structure length is 92
  619.         bytes):
  620.  
  621.         struct client
  622.             {
  623.             char     addr[92];
  624.             key long    clientnbr;
  625.             key char    name[31];
  626.             char    description[61];
  627.             double    balance;
  628.             };
  629.  
  630.         After DDLP compilation, modify the C header file output by DDLP to
  631.         include the proper structure definition.
  632.  
  633.  
  634. DATABASE CURRENCY
  635.  
  636.  
  637. What is Currency?
  638.  
  639.         Currency refers to the record position in a database key file.  It
  640.         is very similiar to the file pointer in an open file. For example,
  641.         when you first open a file using the C run-time library "open"
  642.         function, the file pointer points to the first byte in the file
  643.         (it could point to the last byte depending on how its opened).
  644.         After the file is open, you can seek to different positions in the
  645.         file and read or write data.  The file pointer position is kept
  646.         internally by the operating system.  You could think of this
  647.         position as the current position or "currency".
  648.  
  649.         In CDB, the concepts are very similar.  Each record structure
  650.         defined in a DDL will have an associated currency table when this
  651.         database is opened.
  652.  
  653.  
  654. An Example:
  655.  
  656.         /* sampledb.ddl */
  657.  
  658.         prefix ABC;
  659.  
  660.         struct client
  661.             {
  662.             connect    address key street;
  663.             key long    clientnbr;
  664.             key char    name[31];
  665.             char    description[61];
  666.             double    balance;
  667.             };
  668.  
  669.         struct address
  670.             {
  671.             char    street[31];
  672.             char    city[21];
  673.             char    state[3];
  674.             key char    zip[11];
  675.             key char    telephone[13];
  676.             char    fax[13];
  677.             };
  678.  
  679.         struct setup
  680.             {
  681.             key long    nextclientnbr;
  682.             };
  683.  
  684.  
  685.         When this database is opened using DbOpen, 3 currency tables will
  686.         be initialized to zero.  One for each record type: 'client',
  687.         'address', and 'setup'.  The currency table contains the following
  688.         format:
  689.  
  690.         struct currency_index
  691.             {
  692.             struct
  693.                 {
  694.                 UINT    page;
  695.                 UINT    slot;
  696.                 } keydba[MAXKEY];    /* Array of key dba's */
  697.             ULONG    datadba;    /* Data database address */
  698.             };
  699.  
  700.  
  701.         keydba
  702.  
  703.         The currency table consists of two parts; a key currency (keydba)
  704.         and a data record currency (datadba).  A keydba exists for each
  705.         key defined in the record table.  In the example defined above,
  706.         the 'client' record would use the first two keydba structures in
  707.         the currency_index table for key currency storage.  Records that
  708.         do not have any keys defined would not make use of the keydba part
  709.         of the currency_index.
  710.  
  711.         Lets say that we have three 'client' records in our database.  The
  712.         contents of each are as follows:
  713.  
  714.         Record 1:    1000L,"Daytris","Software Development",0.00
  715.         Record 2:    1001L,"Microsoft","Software Development",10000.00
  716.         Record 3:    1002L,"CompuServe","Computer Services",100.00
  717.  
  718.         When the database is opened, the currency_index for the 'client'
  719.         record, as well as all other records, is null.  In other words,
  720.         "the client record does not have currency".  If we were to issue a:
  721.  
  722.         DbRecordFindNext( "client", "clientnbr");
  723.  
  724.         at this time, an E_NONEXT return value would result.  There is no
  725.         next record to find!  However, if we were to issue a:
  726.  
  727.         DbRecordFindFirst( "client", "clientnbr");
  728.  
  729.         the return value would be 0 indicating a successful call.  After
  730.         this call, the keydba structure within the currency_index for the
  731.         'client' record would contain the appropriate page and slot number
  732.         of the first record for the "clientnbr" index.  In this case, the
  733.         keydba[0] structure within the 'client' currency_index would point
  734.         to client number 1000L, Daytris.
  735.  
  736.         If we were to now issue a:
  737.  
  738.         DbRecrordFindNext( "client", "clientnbr");
  739.  
  740.         the keydba[0] structure within the 'client' currency_index would
  741.         point to the next client sorted by "lClientNbr".  In our example,
  742.         it would point to 1001L, Microsoft.
  743.  
  744.         Keep in mind that we are not retrieving any records, we are only
  745.         setting currency for the 'client' record type.  If we would want
  746.         to retrieve a record, we would use the DbRecordGet... function
  747.         calls.  Using the DbRecordFind... function calls we can essentially
  748.         "seek" to positions within the database based on any index field
  749.         within a record type.
  750.  
  751.  
  752.         datadba
  753.  
  754.         The datadba field in the currency_index is used for "set" currency.
  755.         When we issue a DbSetFind.. function call, the datadba is used to
  756.         locate the current set record.  The datadba field contains the
  757.         actual slot number of the current record.  "Next" and "previous"
  758.         set pointers are stored at the beginning of each data slot in a
  759.         data file.
  760.  
  761.  
  762. Differences Between Find and Get Function Calls
  763.  
  764.         The DbRecordFind... and DbSetFind... function calls only set
  765.         currency for a specific record type.  They do not retrieve records.
  766.         You may want to think of the Find function calls as performing the
  767.         same task as the C run-time lseek function.  Essentially, we are
  768.         seeking to a position in the database.
  769.  
  770.         If you wish to retrieve a record, use the DbRecordGet... or the
  771.         DbSetGet... function calls.  Note:  The DbRecordGet... and
  772.         DbSetGet... function calls call their Find counterparts first, and
  773.         then retrieve the current record.  For example, the
  774.         DbRecordGetFirst function will perform a DbRecordFindFirst and then
  775.         a DbRecordGetCurrent function call.
  776.  
  777.  
  778. Storing Currency Tables
  779.  
  780.         You can retrieve a copy of the current currency_index for each
  781.         record defined in the DDL.  Why would you want to do this?
  782.  
  783.         Lets suppose that you have a database that contains hundreds of
  784.         'client' records.  Your application must be able to display these
  785.         'client' records in a small window, but you don't have enough
  786.         memory to keep all of the 'client' records resident.  Or it may
  787.         be a waste of memory to do so.  This is where storing currency
  788.         tables becomes necessary.  
  789.  
  790.         As previously explained, each record type defined in a DDL has an
  791.         associated currency table.  The contents of a currency table can
  792.         be retrieved or updated at any time.  Therefore, in the example
  793.         explained above, we could retrieve a window of 'client' records
  794.         along with their associated currency_index tables.  Example:
  795.  
  796.  
  797.         UINT GetWindowOfClients( BOOL bFirstTime)
  798.             {
  799.             register short i;
  800.             UINT status;
  801.             struct currency_index currency;
  802.  
  803.             for( i=0 ; i<WINDOW_LINES ; i++)
  804.                 {
  805.                 /* Get the record */
  806.                 if( bFirstTime)
  807.                     {
  808.                     bFirstTime = FALSE;
  809.                     status = DbRecordGetFirst( "client", "clientnbr",
  810.                         &client);
  811.                     }
  812.                 else
  813.                     status = DbRecordGetNext( "client", "clientnbr",
  814.                         &client);
  815.                 if( status)
  816.                     return status;
  817.  
  818.                 /* Get the currency table */
  819.                 status = DbRecordGetCurrency( "client", ¤cy);
  820.  
  821.                 /* Put the record in a window and store along with it
  822.                    the associated currency table */
  823.                 }
  824.             }
  825.  
  826.         After calling this routine, we have a window of 'client' records.
  827.         For each 'client' record we also have an associated currency table.
  828.         If the user were to select a specific 'client' in the window, we
  829.         could retrieve this 'client' with the following database calls:
  830.  
  831.         DbRecordUpdCurrency( "client", ¤cy);
  832.         DbRecordGetCurrent( "client", "clientnbr", &client);
  833.  
  834.         The "currency" structure passed in the DbRecordUpdCurrency call
  835.         represents the currency_index of the selected 'client' record.
  836.         Because we have a currency table stored for each 'client' record
  837.         in the window, we can retrieve any record in the window using
  838.         this method.
  839.  
  840.  
  841.         Deleting a current record
  842.  
  843.         Beware when deleting a current record.  If you are storing a
  844.         series of currency tables as we have done in the example explained
  845.         above, deleting a current record will invalidate currency tables
  846.         that followed this record.  Suppose we have a window of 'client'
  847.         records:
  848.  
  849.         Record 1:    1010L,"ABC Corp.","Diskette Manufacturer",0.00
  850.         Record 2:    1011L,"XYZ  Corp.","Hard Drive Manufacturer",0.00
  851.         Record 3:    1012L,"BYTE Magazine","Software Publication",0.00
  852.         Record 4:    1013L,"Sharp","Electronics",0.00
  853.         Record 5:    1014L,"Collins","Radio Electronics",0.00
  854.  
  855.         We have also stored currency tables associated with each 'client'
  856.         record in the window.
  857.  
  858.         If for example we delete Record 2, "XYZ Corp.", the currency
  859.         tables associated with Records 3, 4, and 5 will now be invalid.
  860.         Remember that currency tables contain the page and slot of a data
  861.         item.  If a record is deleted, the key fields are removed from
  862.         their associated pages.  The data (slots) on a key page are
  863.         compressed to be contiguous.  Therefore, key fields stored after
  864.         the deleted record will be moved up 1 slot.  Or possibly, if the
  865.         slot is the last slot on a page, the page will be removed entirely.
  866.  
  867.         To avoid retaining invalid currency tables in memory after deleting
  868.         a record, currency tables should be re-retrieved after the deletion.
  869.         To do this, start the retrieval with the record before the deleted
  870.         record.  In the example above, Record 2 is being deleted.  After
  871.         the deletion, restore the Record 1 currency table (using
  872.         DbRecordUpdCurrency) and re-retrieve next records and corresponding
  873.         currency tables (using DbRecordGetCurrency)  until the window is
  874.         full.
  875.  
  876.  
  877.         Updating a current record
  878.  
  879.         An update, like the delete described above, can create similar
  880.         problems.  This is only a problem if the key field that was used
  881.         for the retrieval of records is updated.  In this case, the slots
  882.         could be rearranged in an order unknown to the calling application.
  883.         The only way to solve this problem, is to re-retrieve the records
  884.         and their associated currency tables from the beginning after the
  885.         update takes place.
  886.  
  887.  
  888. DATABASE INTERNALS
  889.  
  890.  
  891. Memory Requirements
  892.  
  893.         CDB requires a very small amount of memory to operate.  The
  894.         library allocates all memory required for data access and
  895.         manipulation during the DbOpen call.  Memory is NOT allocated by
  896.         the database during the execution of any other database call.
  897.  
  898.         CDB will consume approximately 45K of code and data space.  A
  899.         portion of this space is allocated when a database is opened.  A
  900.         variable amount of memory is also allocated and depends upon the
  901.         size of the DBD file.  This space is used for DBD record, owner,
  902.         member, and field tables.  To calculate the variable amount of 
  903.         memory that will be required by a DBD, use the following formula:
  904.  
  905.         DBD memory consumption = (number of records * 46) +
  906.             (number of owners * 4) + (number of members * 8) +
  907.             (number of fields * 40)
  908.  
  909.         The DBDLIST utility included in this release will display the
  910.         number of records, owners, members, and fields in a DBD.  As an
  911.         example, the SAMPLEDB.DBD displayed in this document will consume
  912.         only 590 bytes for the tables described above.
  913.  
  914.  
  915. Database Files
  916.  
  917.         Database records are organized in data and key files.  Each record
  918.         type defined in the DDL will have an associated data file.  If any
  919.         key fields exist in this record, the record type will also have a
  920.         key file.  Key files have a .key extension while data files have a
  921.         .dat extension.
  922.  
  923.  
  924.         File Naming
  925.  
  926.         /* sampledb.ddl */
  927.  
  928.         prefix ABC;
  929.  
  930.         struct client
  931.             {
  932.             connect    address key street;
  933.             key long    clientnbr;
  934.             key char    name[31];
  935.             char    description[61];
  936.             double    balance;
  937.             };
  938.  
  939.         struct address
  940.             {
  941.             char    street[31];
  942.             char    city[21];
  943.             char    state[3];
  944.             key char    zip[11];
  945.             key char    telephone[13];
  946.             char    fax[13];
  947.             };
  948.  
  949.         struct setup
  950.             {
  951.             key long    nextclientnbr;
  952.             };
  953.  
  954.         Key and data files are not created until the first record of a
  955.         specific record type is added.  For example, when the first
  956.         'client' record is added to the database, a data and key file will
  957.         be created.  The names used for the .DAT and .KEY file are derived
  958.         as follows:
  959.  
  960.         sprintf( keyfile, "%s%4.4d", prefix, orderinDBD);
  961.         sprintf( datfile, "%s%4.4d", szPrefix, orderinDBD);
  962.  
  963.         The prefix is the prefix defined in the DDL.  In our example, the
  964.         prefix is "ABC".  The orderinDBD is the record number in the
  965.         database definition (.DBD) file.  When DDLP compiles the DDL into
  966.         DBD format, record tables are stored describing each record
  967.         structure definition.  The record tables are stored in alphabetical
  968.         order in the DBD file.  In our example, the record order in the DBD
  969.         is 'address', 'client', then 'setup'.  Therefore, when the first
  970.         'client' record is added to the database, ABC0001.DAT and
  971.         ABC0001.KEY are created.  When the first 'address' record is added,
  972.         ABC0000.DAT and ABC0000.KEY are created.
  973.  
  974.         If a record definiton does not contain a key field, a key file is
  975.         not created for this record.
  976.  
  977.  
  978.         Key File Layout
  979.  
  980.         Key files are organized as a series of pages.  Pages contain a
  981.         series of slots.  The slots contain the key data.  Slots on a page
  982.         are in sorted order.  A key file will contain pages of keys for a
  983.         specific record type.  For example, in SAMPLEDB.DDL shown above,
  984.         the 'client' key file will contain pages of keys for the 'client'
  985.         record.  
  986.  
  987.         Some pages will contain client numbers and some pages will contain
  988.         client names.  A page will not contain both client numbers and
  989.         client names.
  990.  
  991.         The key file structures are listed below:
  992.  
  993.         struct  key_file_index
  994.             {
  995.             CHAR    name[12];    /* Key file name */
  996.             UINT    nextavailpage;    /* Next available page */
  997.             UINT    firstdelpage;    /* First page in the delete */
  998.                             /* chain. */
  999.             UINT    pagenbr[MAXKEY];/* Key 1st page index */
  1000.             };
  1001.  
  1002.         This structure is included at the beginning of every key file.  It
  1003.         contains necessary pointers for finding the next available page,
  1004.         first deleted page in the delete chain, and the first page for
  1005.         each key field defined in the record.
  1006.  
  1007.         struct  key_page_index
  1008.             {
  1009.             UINT    prevpage;    /* Previous page in sort tree */
  1010.             UINT    nextpage;    /* Next page in sort tree */
  1011.             UINT    slotsused;    /* Number of slots used on page */
  1012.             UINT    slotsize;    /* Size of key slot */
  1013.             UINT    flags;            /* Bit 0 - page is full */
  1014.             };
  1015.  
  1016.         This structure is included at the beginning of each page in the
  1017.         key file.  The slots in the key file consist of nothing but raw
  1018.         key field data.
  1019.  
  1020.  
  1021.         Data File Layout
  1022.  
  1023.         Data files do not contain pages.  They are organized as a series
  1024.         of slots in a file.  Pages are not needed here because data files
  1025.         contain only record data.  They are indexed by their respective
  1026.         key files.
  1027.  
  1028.         The data file structures are listed below:
  1029.  
  1030.         struct  data_file_index
  1031.             {
  1032.             CHAR    name[12];    /* Data file name */
  1033.             ULONG    nextavailslot;    /* Next available slot */
  1034.             ULONG    firstdelslot;    /* First slot in the delete */
  1035.                                 /* chain. */
  1036.             UINT    slotsize;    /* Size of data slot */
  1037.             CHAR    filler[10];
  1038.             };
  1039.  
  1040.         This structrure is included at the beginning of every data file.
  1041.         It contains necessary pointers for finding the next available slot,
  1042.         first deleted slot in the delete chain, and the data slot size.
  1043.  
  1044.         struct  data_slot_index
  1045.             {
  1046.             UINT    offsettodata;    /* Offset to actual data */
  1047.             ULONG    nextdel;    /* DBA of next member in the */
  1048.                                 /* delete chain. */
  1049.             };
  1050.  
  1051.         This structure is included at the beginning of each data slot.  A
  1052.         data slot also contains owner and/or member data if the record type
  1053.         is an owner of or member of another record.  The owner and member
  1054.         pointer tables are not shown here.  In summary, a data slot
  1055.         contains a data_slot_index, owner data tables, member data table,
  1056.         followed by the actual data record.
  1057.  
  1058.  
  1059. Modifying Internal Definitions
  1060.  
  1061.         It is relatively easy to change some of the global definitions
  1062.         used CDB.  In some extreme cases, modification may be necessary.
  1063.         This, of course, depends on your database model (data definition
  1064.         file).  Source code is required to make any of the changes to the
  1065.         definitions listed below.
  1066.  
  1067.         All definitions described are included in DBMGR.H.
  1068.  
  1069.  
  1070.         #define NBRHANDLES  12
  1071.  
  1072.         This value is the number of database files that can be open at
  1073.         one time.  A data file exists for every record defined in the DDL
  1074.         if at least one record of that type has been added.  If the DDL
  1075.         structure definition contains one or more key fields, a key file
  1076.         will also be created.
  1077.  
  1078.         struct client
  1079.             {
  1080.             key long    lClientNbr;
  1081.             key char    szName[31];
  1082.             char    szDescription[61];
  1083.             double    dBalance;
  1084.             };
  1085.  
  1086.         In this DDL example, two files will be created when the first
  1087.         record of this type is added to the database.  A data file will
  1088.         be created and because at least 1 key field exists, a key file
  1089.         will also be created.
  1090.  
  1091.         CDB uses an LRU (least recently used) algorithm to manage
  1092.         database file handles.  If CDB needs to open a file and 12
  1093.         database files are already open, CDB closes the least recently
  1094.         used handle and proceeds to open the new file.  The new file
  1095.         handle is then placed in the LRU table.
  1096.  
  1097.         If your database model contains more than 12 database files,
  1098.         database perfomance may be enhanced by increasing the NBRHANDLES
  1099.         value.  Note: The maximum number of file handles available for a
  1100.         single task under DOS is 20.  5 are reserved for internal use.
  1101.         If you leave NBRHANDLES defined as 12, only 3 are available for
  1102.         your application.
  1103.  
  1104.  
  1105.         #define MAXKEY  8
  1106.  
  1107.         This value is the maximum number of key fields that a single
  1108.         record definition can contain.  Increase this value only if you
  1109.         have more than 8 key fields defined in a single record definition.
  1110.  
  1111.  
  1112.         #define KEYPAGESIZE  512
  1113.  
  1114.         Key fields are stored in sorted order in slots on pages.  A key
  1115.         file is made up of a header and a series of these pages.
  1116.         KEYPAGESIZE is the size of a key page.  If your database key
  1117.         fields are very large, you might increase the performance of the 
  1118.         database by increasing this value.  If modified, KEYPAGESIZE
  1119.         should be a multiple of the average key field length.  Note:
  1120.         The larger the key page size, the longer the access time for
  1121.         reads and writes.
  1122.  
  1123.  
  1124.         #define NBRPAGES  16
  1125.  
  1126.         This value is the number of key pages that are buffered in RAM
  1127.         by CDB.  These buffers are managed using an LRU (least recently
  1128.         used) algorithm for maximum efficiency.
  1129.  
  1130.  
  1131.         #define DATAPAGESIZE  2048
  1132.  
  1133.         Data records are stored in slots on pages.  The pages are stored
  1134.         in the data file (.DAT).  This value is the size of the data pages.
  1135.         It is recommended that this value be a power of 2.
  1136.  
  1137.  
  1138.         #define DATASLOTSIZE  1024
  1139.  
  1140.         This value is the maximum size of a data slot.  A data slot
  1141.         contains a small header, followed by owner tables (if any),
  1142.         followed by member tables (if any), followed by the actual data.
  1143.         You will need to increase this value if your record sizes, when
  1144.         plugged into the formula below, exceed 1024.
  1145.  
  1146.         Formula:
  1147.  
  1148.         6 +
  1149.         (number of member record types this record can own * 8) +
  1150.         (number of owner record types that can own this record * 12) +
  1151.         C structure length (in bytes)
  1152.  
  1153.         If you have very large C structures you should check them.  It is
  1154.         recommended that DATASLOTSIZE be a power of 2.
  1155.  
  1156.  
  1157.         Example:
  1158.  
  1159.         /* sampledb.ddl */
  1160.  
  1161.         struct client
  1162.             {
  1163.             connect    address key street;
  1164.             key long    clientnbr;
  1165.             key char    name[31];
  1166.             char    description[61];
  1167.             double    balance;
  1168.             };
  1169.  
  1170.         struct address
  1171.             {
  1172.             char    street[31];
  1173.             char    city[21];
  1174.             char    state[3];
  1175.             key char    zip[11];
  1176.             key char    telephone[13];
  1177.             char    fax[13];
  1178.             };
  1179.  
  1180.         In this DDL example, the size of a 'client' data slot would be:
  1181.  
  1182.         6 +
  1183.         (1 * 8) +
  1184.         (0 * 12) +
  1185.         104 = 118
  1186.  
  1187.         The size of an 'address' data slot would be:
  1188.  
  1189.         6 +
  1190.         (0 * 8) +
  1191.         (1 * 12) +
  1192.         92 = 110
  1193.  
  1194.  
  1195. UTILITIES
  1196.  
  1197.  
  1198. DDLP.EXE
  1199.  
  1200.         DDLP is the Data Definition Language Parser (compiler).  It reads
  1201.         the DDL file and creates a binary database definition file with a
  1202.         .DBD extenstion.  DDLP also creates a C header file with a .H
  1203.         extension.
  1204.  
  1205.         The DBD file name is used with the DbOpen function call.  The
  1206.         DbOpen function passes the DBD file name as a parameter.  The DBD
  1207.         file is read into memory by CDB and serves as a roadmap for the
  1208.         database.
  1209.  
  1210.         The maximum size of a .DDL file that DDLP can process is 65535
  1211.         bytes.  A complete list of DDLP error messages are provided in the
  1212.         'Error Messages' section in this manual.
  1213.  
  1214.  
  1215.         Syntax:
  1216.  
  1217.         DDLP filename(.ddl)
  1218.  
  1219.  
  1220.         Example:
  1221.  
  1222.         DDLP sampledb.ddl
  1223.  
  1224.         In this example, DDLP will create SAMPLEDB.DBD and SAMPLEDB.H if
  1225.         the compilation is successful.
  1226.  
  1227.  
  1228. DBDLIST.EXE
  1229.  
  1230.         DBDLIST displays the contents of the binary database definition
  1231.         file (.DBD) created by DDLP.  A header, record definitions, owner
  1232.         definitions, member definitions, and field definitions are
  1233.         displayed.
  1234.  
  1235.         DBDLIST does not display the contents of any data or key files.
  1236.  
  1237.  
  1238.         Syntax:
  1239.  
  1240.         DBDLIST filename.dbd
  1241.  
  1242.  
  1243.         Example:
  1244.  
  1245.         DBDLIST sampledb.dbd
  1246.  
  1247.  
  1248. USING THE C-API
  1249.  
  1250.  
  1251. Introduction
  1252.  
  1253.         The CDB C-API library is callable from both C and C++ modules.
  1254.         Over 30 functions are available.  Function prototypes are defined
  1255.         in DBMGR.H.
  1256.  
  1257.  
  1258. Functions by Category
  1259.  
  1260.         Database Management
  1261.  
  1262.         DbClose                Close a database.
  1263.         DbFlush                Flush all data files to disk.
  1264.         DbOpen                Open a database.
  1265.  
  1266.  
  1267.         Record Management
  1268.  
  1269.         DbRecordAdd        Add a record.
  1270.         DbRecordDelete            Delete a record.
  1271.         DbRecordUpdate            Update a record.
  1272.  
  1273.  
  1274.         Record Find
  1275.  
  1276.         DbRecordFindByKey    Find a record by key value.
  1277.         DbRecordFindFirst    Find the first record.
  1278.         DbRecordFindLast    Find the last record.
  1279.         DbRecordFindNext    Find the next record.
  1280.         DbRecordFindPrev    Find the previous record.
  1281.  
  1282.  
  1283.         Record Retrieval
  1284.  
  1285.         DbRecordGetByKey    Get a record by key value.
  1286.         DbRecordGetCurrent    Get the current record.
  1287.         DbRecordGetFirst    Get the first record.
  1288.         DbRecordGetLast            Get the last record.
  1289.         DbRecordGetNext            Get the next record.
  1290.         DbRecordGetPrev            Get the previous record.
  1291.  
  1292.  
  1293.         Record Currency
  1294.  
  1295.         DbRecordGetCurrency    Get the currency table of a record type.
  1296.         DbRecordUpdCurrency    Update the currency table of a record type.
  1297.  
  1298.  
  1299.         Set Management
  1300.  
  1301.         DbSetAdd        Make a set connection between two records.
  1302.         DbSetDelete        Remove a set connection between two records.
  1303.  
  1304.  
  1305.         Set Find
  1306.  
  1307.         DbSetFindFirst        Find the first member record in an
  1308.                                 owner/member relationship.
  1309.         DbSetFindLast        Find the last member record in an
  1310.                                 owner/member relationship.
  1311.         DbSetFindNext        Find the next member record in an
  1312.                                 owner/member relationship.
  1313.         DbSetFindPrev        Find the previous member record in an
  1314.                                 owner/member relationship.
  1315.  
  1316.  
  1317.         Set Retrieval
  1318.  
  1319.         DbSetGetFirst        Get the first member record in an
  1320.                                 owner/member relationship.
  1321.         DbSetGetLast        Get the last member record in an
  1322.                                 owner/member relationship.
  1323.         DbSetGetNext        Get the next member record in an
  1324.                                 owner/member relationship.
  1325.         DbSetGetOwner            Get the owner record of a member in an 
  1326.                                 owner/member relationship.
  1327.         DbSetGetPrev        Get the previous member record in an
  1328.                                 owner/member relationship.
  1329.  
  1330.  
  1331. DbClose
  1332. -------
  1333.  
  1334. Summary
  1335.  
  1336.         INT DbClose( void);
  1337.  
  1338.  
  1339. Description
  1340.  
  1341.         The DbClose function closes the open database.  All database
  1342.         files are closed and memory is deallocated.
  1343.  
  1344.  
  1345. Return Value
  1346.  
  1347.         A 0 is returned if no error occurred.  Otherwise the return code
  1348.         can be E_DOS.  See the 'Error Messages' section for more detail
  1349.         on this value.
  1350.  
  1351.  
  1352. Example
  1353.  
  1354.         #include "dbmgr.h"
  1355.  
  1356.         void Function()
  1357.             {
  1358.             INT status;
  1359.  
  1360.             if( status = DbOpen( ".\\", "test.dbd"))
  1361.                 {
  1362.                 /* Database not opened */
  1363.                 }
  1364.  
  1365.             /* Other CDB calls... */
  1366.  
  1367.             if( status = DbClose())
  1368.                 {
  1369.                 /* Database not closed */
  1370.                 }
  1371.             }
  1372.  
  1373.  
  1374. DbFlush
  1375. -------
  1376.  
  1377. Summary
  1378.  
  1379.         INT DbFlush();
  1380.  
  1381.  
  1382. Description
  1383.  
  1384.         The DbFlush function forces all data written to the database to
  1385.         disk.  Dirty memory pages are written to disk and all open files
  1386.         are closed and then reopened.
  1387.  
  1388.  
  1389. Return Value
  1390.  
  1391.         A 0 is returned if no error occurred.  Otherwise the return code
  1392.         can be E_DOS.  See the 'Error Messages' section for more detail
  1393.         on this value.
  1394.  
  1395.  
  1396. Example
  1397.  
  1398.         #include "dbmgr.h"
  1399.  
  1400.         void Function( struct client far *pClient)
  1401.             {
  1402.             INT status;
  1403.  
  1404.             if( status = DbRecordUpdate( "client", pClient))
  1405.                 {
  1406.                 /* Record not updated */
  1407.                 }
  1408.  
  1409.             if( status = DbFlush())
  1410.                 {
  1411.                 /* Database not flushed */
  1412.                 }
  1413.             }
  1414.  
  1415.  
  1416. DbOpen
  1417. ------
  1418.  
  1419. Summary
  1420.  
  1421.         INT DbOpen( char *pDbDir, char *pDbName)
  1422.  
  1423.  
  1424. Parameters
  1425.  
  1426.         pDbDir          CHAR *  Identifies the directory where CDB will
  1427.                         attempt to open the .DBD (Database Definition)
  1428.                         file.  CDB will also attempt to open and/or create
  1429.                         all associated database files in this directory.
  1430.                         If NULL, CDB will use the current directory.
  1431.                         Note: If a directory name is present, it must
  1432.                         end with a backslash.  e.g. "C:\\PRODUCTA\\".
  1433.  
  1434.         pDbName         CHAR *  Identifies the .DBD (Database Definition)
  1435.                         file.
  1436.  
  1437.  
  1438. Description
  1439.  
  1440.         The DbOpen function opens a CDB database.  The database definition
  1441.         file (pDbName) is created by DDLP.EXE.
  1442.  
  1443.  
  1444. Return Value
  1445.  
  1446.         A 0 is returned if no error occurred.  Otherwise the return code
  1447.         can be E_DOS.  See the 'Error Messages' section for more detail
  1448.         on this value.
  1449.  
  1450.  
  1451. Example
  1452.  
  1453.         #include "dbmgr.h"
  1454.  
  1455.         void Function()
  1456.             {
  1457.             INT status;
  1458.  
  1459.             if( status = DbOpen( "C:\\PRODUCTA\\", "test.dbd"))
  1460.                 {
  1461.                 /* Error opening database */
  1462.                 }
  1463.  
  1464.             /* Other CDB calls... */
  1465.             }
  1466.  
  1467.  
  1468. DbRecordAdd
  1469. -----------
  1470.  
  1471. Summary
  1472.  
  1473.         INT DbRecordAdd( CHAR *pRecName, VOID *pData)
  1474.  
  1475.  
  1476. Parameters
  1477.  
  1478.         pRecName    CHAR *  Pointer to the record name.
  1479.  
  1480.         pData            VOID *  Pointer to the record data.
  1481.  
  1482.  
  1483. Description
  1484.  
  1485.         The DbRecordAdd function adds a record to the database.
  1486.  
  1487.  
  1488. Return Value
  1489.  
  1490.         A 0 is returned if no error occurred.  Otherwise the return code
  1491.         can be E_DOS or E_NORECNAME.  See the 'Error Messages' section
  1492.         for more detail on these values.
  1493.  
  1494.  
  1495. Example
  1496.  
  1497.         #include "dbmgr.h"
  1498.  
  1499.         INT Function( CHAR *pClientData)
  1500.             {
  1501.             INT status;
  1502.  
  1503.             if( status = DbRecordAdd( "client", pClientData))
  1504.                 {
  1505.                 /* Error adding record */
  1506.                 }
  1507.  
  1508.             return status;
  1509.             }
  1510.  
  1511.  
  1512. DbRecordDelete
  1513. --------------
  1514.  
  1515. Summary
  1516.  
  1517.         INT DbRecordDelete( CHAR *pRecName)
  1518.  
  1519.  
  1520. Parameters
  1521.  
  1522.         pRecName        CHAR *  Pointer to the record name.
  1523.  
  1524.  
  1525. Description
  1526.  
  1527.         The DbRecordDelete function deletes a record from the database.
  1528.         The record deleted is the current record of the pRecName type.
  1529.  
  1530.  
  1531. Return Value
  1532.  
  1533.         A 0 is returned if no error occurred.  Otherwise the return code
  1534.         can be E_DOS, E_NORECNAME, or E_NOCURRENT.  See the 'Error
  1535.         Messages' section for more detail on these values.
  1536.  
  1537.  
  1538. Example
  1539.  
  1540.         #include "dbmgr.h"
  1541.  
  1542.         void Function()
  1543.             {
  1544.             INT status;
  1545.             LONG clientnbr = 1000L;
  1546.  
  1547.             if( status = DbRecordFindByKey( "client", "clientnbr",
  1548.                 &clientnbr))
  1549.                 {
  1550.                 /* Record not found */
  1551.                 }
  1552.  
  1553.             if( status = DbRecordDelete( "client"))
  1554.                 {
  1555.                 /* Error deleting record */
  1556.                 }
  1557.             }
  1558.  
  1559.  
  1560. DbRecordFindByKey
  1561. -----------------
  1562.  
  1563. Summary
  1564.  
  1565.         INT DbRecordFindByKey( CHAR *pRecName, CHAR *pFldName, VOID *pKey)
  1566.  
  1567.  
  1568. Parameters
  1569.  
  1570.         pRecName    CHAR *  Pointer to the record name.
  1571.  
  1572.         pFldName    CHAR *  Pointer to the field name.  Must be a key
  1573.                         field.
  1574.  
  1575.         pKey            VOID *  Pointer to the key data to be used for the
  1576.                         record search.
  1577.  
  1578.  
  1579. Description
  1580.  
  1581.         The DbRecordFindByKey function searches for a specific record
  1582.         using a key field and key value.
  1583.  
  1584.  
  1585. Return Value
  1586.  
  1587.         A 0 is returned if no error occurred.  Otherwise the return code
  1588.         can be E_DOS, E_NORECNAME, E_NOFLDNAME, E_NOTAKEY, E_NOTFOUND, or
  1589.         E_NEXTGUESS.  See the 'Error Messages' section for more detail on
  1590.         these values.
  1591.  
  1592.  
  1593. Example
  1594.  
  1595.         #include "dbmgr.h"
  1596.  
  1597.         void Function()
  1598.             {
  1599.             INT status;
  1600.             LONG clientnbr = 1000L;
  1601.  
  1602.             if( status = DbRecordFindByKey( "client", "lClientNbr",
  1603.                 &clientnbr))
  1604.                 {
  1605.                 /* Record not found */
  1606.                 }
  1607.             }
  1608.  
  1609.  
  1610. DbRecordFindFirst
  1611. -----------------
  1612.  
  1613. Summary
  1614.  
  1615.         INT DbRecordFindFirst( CHAR *pRecName, CHAR *pFldName)
  1616.  
  1617.  
  1618. Parameters
  1619.  
  1620.         pRecName    CHAR *  Pointer to the record name.
  1621.  
  1622.         pFldName    CHAR *  Pointer to the field name. Must be a key
  1623.                         field.
  1624.  
  1625.  
  1626. Description
  1627.  
  1628.         The DbRecordFindFirst function sets the database currency to the
  1629.         first logical record sorted by pFldName.  For more on currency,
  1630.         see the Database Currency section in this manual.
  1631.  
  1632.  
  1633. Return Value
  1634.  
  1635.         A 0 is returned if no error occurred.  Otherwise the return code
  1636.         can be E_DOS, E_NORECNAME, E_NOFLDNAME, E_NOTAKEY, or E_NOTFOUND.
  1637.         See the 'Error Messages' section for more detail on these values.
  1638.  
  1639.  
  1640. Example
  1641.  
  1642.         #include "dbmgr.h"
  1643.  
  1644.         void Function()
  1645.             {
  1646.             INT status;
  1647.  
  1648.             /* Delete all client records in database */
  1649.             while( ! DbRecordFindFirst( "client", "clientnbr"))
  1650.                 {
  1651.                 if( status = DbRecordDelete( "client"))
  1652.                     {
  1653.                     /* Error deleting record */
  1654.                     }
  1655.                 }
  1656.             }
  1657.  
  1658.  
  1659. DbRecordFindLast
  1660. ----------------
  1661.  
  1662. Summary
  1663.  
  1664.         INT DbRecordFindLast( CHAR *pRecName, CHAR *pFldName)
  1665.  
  1666.  
  1667. Parameters
  1668.  
  1669.         pRecName    CHAR *  Pointer to the record name.
  1670.  
  1671.         pFldName    CHAR *  Pointer to the field name. Must be a key
  1672.                         field.
  1673.  
  1674.  
  1675. Description
  1676.  
  1677.         The DbRecordFindLast function sets the database currency to the
  1678.         last logical record sorted by pFldName.  For more on currency, see
  1679.         the Database Currency section in this manual.
  1680.  
  1681.  
  1682. Return Value
  1683.  
  1684.         A 0 is returned if no error occurred.  Otherwise the return code
  1685.         can be E_DOS, E_NORECNAME, E_NOFLDNAME, E_NOTAKEY, or E_NOTFOUND.
  1686.         See the 'Error Messages' section for more detail on these values.
  1687.  
  1688.  
  1689. Example
  1690.  
  1691.         #include "dbmgr.h"
  1692.  
  1693.         void Function()
  1694.             {
  1695.             INT status;
  1696.  
  1697.             /* Delete all client records in database */
  1698.             while( ! DbRecordFindLast( "client", "clientnbr"))
  1699.                 {
  1700.                 if( status = DbRecordDelete( "client"))
  1701.                     {
  1702.                     /* Error deleting record */
  1703.                     }
  1704.                 }
  1705.             }
  1706.  
  1707.  
  1708. DbRecordFindNext
  1709. ----------------
  1710.  
  1711. Summary
  1712.  
  1713.         INT DbRecordFindNext( CHAR *pRecName, CHAR *pFldName)
  1714.  
  1715.  
  1716. Parameters
  1717.  
  1718.         pRecName    CHAR *  Pointer to the record name.
  1719.  
  1720.         pFldName    CHAR *  Pointer to the field name. Must be a key
  1721.                         field.
  1722.  
  1723.  
  1724. Description
  1725.  
  1726.         The DbRecordFindNext function sets the database currency to the
  1727.         next logical record sorted by pFldName.  The record must have
  1728.         currency before this call is executed.  For more on currency, see
  1729.         the Database Currency section in this manual.
  1730.  
  1731.  
  1732. Return Value
  1733.  
  1734.         A 0 is returned if no error occurred.  Otherwise the return code
  1735.         can be E_DOS, E_NORECNAME, E_NOFLDNAME, E_NOTAKEY, E_NOTFOUND,
  1736.         E_NOCURRENT, or E_NONEXT.  See the 'Error Messages' section for
  1737.         more detail on these values.
  1738.  
  1739.  
  1740. Example
  1741.  
  1742.         #include "dbmgr.h"
  1743.  
  1744.         INT Function()
  1745.             {
  1746.             /* Down arrow key pressed, check for next */
  1747.             /* record in database. */
  1748.             return( DbRecordFindNext( "client", "clientnbr"));
  1749.             }
  1750.  
  1751.  
  1752. DbRecordFindPrev
  1753. ----------------
  1754.  
  1755. Summary
  1756.  
  1757.         INT DbRecordFindPrev( CHAR *pRecName, CHAR *pFldName)
  1758.  
  1759.  
  1760. Parameters
  1761.  
  1762.         pRecName    CHAR *  Pointer to the record name.
  1763.  
  1764.         pFldName    CHAR *  Pointer to the field name. Must be a key
  1765.                         field.
  1766.  
  1767.  
  1768. Description
  1769.  
  1770.         The DbRecordFindPrev function sets the database currency to the
  1771.         previous logical record sorted by pFldName.  The record must have
  1772.         currency before this call is executed.  For more on currency, see
  1773.         the Database Currency section in this manual.
  1774.  
  1775.  
  1776. Return Value
  1777.  
  1778.         A 0 is returned if no error occurred.  Otherwise the return code
  1779.         can be E_DOS, E_NORECNAME, E_NOFLDNAME, E_NOTAKEY, E_NOTFOUND,
  1780.         E_NOCURRENT, or E_NOPREV.  See the 'Error Messages' section for
  1781.         more detail on these values.
  1782.  
  1783.  
  1784. Example
  1785.  
  1786.         #include "dbmgr.h"
  1787.  
  1788.         INT Function()
  1789.             {
  1790.             /* Up arrow key pressed, check for previous */
  1791.             /* record in database. */
  1792.             return( DbRecordFindPrev( "client", "clientnbr"));
  1793.             }
  1794.  
  1795.  
  1796. DbRecordGetByKey
  1797. ----------------
  1798.  
  1799. Summary
  1800.  
  1801.         INT DbRecordGetByKey( CHAR *pRecName, CHAR *pFldName, VOID *pTarget,
  1802.                 VOID * pKey)
  1803.  
  1804.  
  1805. Parameters
  1806.  
  1807.         pRecName    CHAR *  Pointer to the record name.
  1808.  
  1809.         pFldName    CHAR *  Pointer to the field name. Must be a key
  1810.                         field.
  1811.  
  1812.         pTarget            VOID *  Pointer to the storage area for the record
  1813.                         data.
  1814.  
  1815.         pKey            VOID *  Pointer to the key data.
  1816.  
  1817.  
  1818. Description
  1819.  
  1820.         The DbRecordGetByKey function retrieves a record using a key value.
  1821.         If the exact match cannot be found the function will return
  1822.         E_NEXTGUESS specifying that the data returned is the next best
  1823.         guess.
  1824.  
  1825.  
  1826. Return Value
  1827.  
  1828.         A 0 is returned if no error occurred.  Otherwise the return code
  1829.         can be E_DOS, E_NORECNAME, E_NOFLDNAME, E_NOTAKEY, E_NOTFOUND, or
  1830.         E_NEXTGUESS.  See the 'Error Messages' section for more detail on
  1831.         these values.
  1832.  
  1833.  
  1834. Example
  1835.  
  1836.         #include "dbmgr.h"
  1837.  
  1838.         void Function()
  1839.             {
  1840.             INT status;
  1841.             LONG key = 1000L;
  1842.             CLIENT client;
  1843.  
  1844.             /* Get client record with client number equal 1000L */
  1845.             if( status = DbRecordGetByKey( "client", "clientnbr", &client,
  1846.                 &key))
  1847.                 {
  1848.                 /* Client not retrieved */
  1849.                 }
  1850.             }
  1851.  
  1852.  
  1853. DbRecordGetCurrency
  1854. -------------------
  1855.  
  1856. Summary
  1857.  
  1858.         INT DbRecordGetCurrency( CHAR *pRecName, VOID *pTarget)
  1859.  
  1860.  
  1861. Parameters
  1862.  
  1863.         pRecName    CHAR *  Pointer to the record name.
  1864.  
  1865.         pTarget            VOID *  Pointer to the storage area for the currency
  1866.                         information.  
  1867.  
  1868.  
  1869. Description
  1870.  
  1871.         The DbRecordGetCurrency function retrieves the current currency
  1872.         table for a specific record.  For more on currency, see the
  1873.         Database Currency section in this manual.
  1874.  
  1875.  
  1876. Return Value
  1877.  
  1878.         A 0 is returned if no error occurred.  Otherwise the return code
  1879.         can be E_DOS, or E_NORECNAME.  See the 'Error Messages' section for
  1880.         more detail on these values.
  1881.  
  1882.  
  1883. Example
  1884.  
  1885.         #include "dbmgr.h"
  1886.  
  1887.         void Function()
  1888.             {
  1889.             INT status;
  1890.             struct currency_index currency;
  1891.  
  1892.             /* Get the currency for the client record */
  1893.             if( status = DbRecordGetCurrency( "client", ¤cy))
  1894.                 {
  1895.                 /* Currency not retrieved */
  1896.                 }
  1897.  
  1898.             /* Other processing goes here... */
  1899.  
  1900.             /* Restore the currency for the client record */
  1901.             if( status = DbRecordUpdCurrency( "client", ¤cy))
  1902.                 {
  1903.                 /* Currency not updated */
  1904.                 }
  1905.             }
  1906.  
  1907.  
  1908. DbRecordGetCurrent
  1909. ------------------
  1910.  
  1911. Summary
  1912.  
  1913.         INT DbRecordGetCurrent( CHAR *pRecName, VOID *pTarget)
  1914.  
  1915.  
  1916. Parameters
  1917.  
  1918.         pRecName    CHAR *  Pointer to the record name.
  1919.  
  1920.         pTarget            VOID *  Pointer to the storage area for the record
  1921.                         data.
  1922.  
  1923.  
  1924. Description
  1925.  
  1926.         The DbRecordGetCurrent function retrieves the record that has
  1927.         currency (or 'is current') for that record type (record name).
  1928.         Each record type has its own currency table.  For more on currency,
  1929.         see the Database Currency section in this manual.
  1930.  
  1931.  
  1932. Return Value
  1933.  
  1934.         A 0 is returned if no error occurred.  Otherwise the return code
  1935.         can be E_DOS, E_NORECNAME, or E_NOCURRENT.  See the 'Error Messages'
  1936.         section for more detail on these values.
  1937.  
  1938.  
  1939. Example
  1940.  
  1941.         #include "dbmgr.h"
  1942.  
  1943.         void Function()
  1944.             {
  1945.             INT status;
  1946.             LONG clientnbr = 1000L;
  1947.             CLIENT client;
  1948.  
  1949.             /* Check for client #1000 */
  1950.             if( status = DbRecordFindByKey( "client", "lClientNbr",
  1951.                 &clientnbr))
  1952.                 {
  1953.                 /* Record not found */
  1954.                 }
  1955.  
  1956.             /* Retrieve it */
  1957.             if( status = DbRecordGetCurrent( "client", &client))
  1958.                 {
  1959.                 /* Record not retrieved */
  1960.                 }
  1961.             }
  1962.  
  1963.  
  1964. DbRecordGetFirst
  1965. ----------------
  1966.  
  1967. Summary
  1968.  
  1969.         INT DbRecordGetFirst( CHAR *pRecName, CHAR *pFldName, VOID *pTarget)
  1970.  
  1971.  
  1972. Parameters
  1973.  
  1974.         pRecName    CHAR *  Pointer to the record name.
  1975.  
  1976.         pFldName    CHAR *  Pointer to the field name.  Must be a key
  1977.                         field.
  1978.  
  1979.         pTarget            VOID *  Pointer to the storage area for the record
  1980.                         data.
  1981.  
  1982.  
  1983. Description
  1984.  
  1985.         The DbRecordGetFirst function retrieves the first record by the
  1986.         key field passed.  After this call, the currency for this record
  1987.         type is set to the first record.
  1988.  
  1989.  
  1990. Return Value
  1991.  
  1992.         A 0 is returned if no error occurred.  Otherwise the return code
  1993.         can be E_DOS, E_NORECNAME, E_NOFLDNAME, E_NOTAKEY, or E_NOTFOUND.
  1994.         See the 'Error Messages' section for more detail on these values.
  1995.  
  1996.  
  1997. Example
  1998.  
  1999.         #include "dbmgr.h"
  2000.  
  2001.         void Function()
  2002.             {
  2003.             INT status;
  2004.             CLIENT client;
  2005.  
  2006.             /* Get the first record sorted by client number*/
  2007.             if( status = DbRecordGetFirst( "client", "clientnbr", &client))
  2008.                 {
  2009.                 /* Record not retrieved */
  2010.                 }
  2011.             }
  2012.  
  2013.  
  2014. DbRecordGetLast
  2015. ---------------
  2016.  
  2017. Summary
  2018.  
  2019.         INT DbRecordGetLast( CHAR *pRecName, CHAR *pFldName, VOID *pTarget)
  2020.  
  2021.  
  2022. Parameters
  2023.  
  2024.         pRecName    CHAR *  Pointer to the record name.
  2025.  
  2026.         pFldName    CHAR *  Pointer to the field name.  Must be a key
  2027.                         field.
  2028.  
  2029.         pTarget            VOID *  Pointer to the storage area for the record
  2030.                         data.
  2031.  
  2032.  
  2033. Description
  2034.  
  2035.         The DbRecordGetLast function retrieves the last record by the key
  2036.         field passed.  After this call, the currency for this record type
  2037.         is set to the last record.
  2038.  
  2039.  
  2040. Return Value
  2041.  
  2042.         A 0 is returned if no error occurred.  Otherwise the return code
  2043.         can be E_DOS, E_NORECNAME, E_NOFLDNAME, E_NOTAKEY, or E_NOTFOUND.
  2044.         See the 'Error Messages' section for more detail on these values.
  2045.  
  2046.  
  2047. Example
  2048.  
  2049.         #include "dbmgr.h"
  2050.  
  2051.         void Function()
  2052.             {
  2053.             INT status;
  2054.             CLIENT client;
  2055.  
  2056.             /* Get the last record sorted by client number*/
  2057.             if( status = DbRecordGetLast( "client", "clientnbr", &client))
  2058.                 {
  2059.                 /* Record not retrieved */
  2060.                 }
  2061.             }
  2062.  
  2063.  
  2064. DbRecordGetNext
  2065. ---------------
  2066.  
  2067. Summary
  2068.  
  2069.         INT DbRecordGetNext( CHAR *pRecName, CHAR *pFldName, VOID *pTarget)
  2070.  
  2071.  
  2072. Parameters
  2073.  
  2074.         pRecName    CHAR *  Pointer to the record name.
  2075.  
  2076.         pFldName    CHAR *  Pointer to the field name.  Must be a key
  2077.                         field.
  2078.  
  2079.         pTarget            VOID *  Pointer to the storage area for the record
  2080.                         data.
  2081.  
  2082.  
  2083. Description
  2084.  
  2085.         The DbRecordGetNext function retrieves the next record by the key
  2086.         field passed.  After this call, the currency for this record type
  2087.         is set to the record retrieved.
  2088.  
  2089.  
  2090. Return Value
  2091.  
  2092.         A 0 is returned if no error occurred.  Otherwise the return code
  2093.         can be E_DOS, E_NORECNAME, E_NOFLDNAME, E_NOTAKEY, E_NOTFOUND,
  2094.         E_NOCURRENT, or E_NONEXT.  See the 'Error Messages' section for
  2095.         more detail on these values.
  2096.  
  2097.  
  2098. Example
  2099.  
  2100.         #include "dbmgr.h"
  2101.  
  2102.         void Function()
  2103.             {
  2104.             INT status;
  2105.             CLIENT client;
  2106.  
  2107.             /* Get the next record sorted by client number*/
  2108.             if( status = DbRecordGetNext( "client", "clientnbr", &client))
  2109.                 {
  2110.                 /* Record not retrieved */
  2111.                 }
  2112.             }
  2113.  
  2114.  
  2115. DbRecordGetPrev
  2116. ---------------
  2117.  
  2118. Summary
  2119.  
  2120.         INT DbRecordGetPrev( CHAR *pRecName, CHAR *pFldName, VOID *pTarget)
  2121.  
  2122.  
  2123. Parameters
  2124.  
  2125.         pRecName    CHAR *  Pointer to the record name.
  2126.  
  2127.         pFldName    CHAR *  Pointer to the field name.  Must be a key
  2128.                         field.
  2129.  
  2130.         pTarget            VOID *  Pointer to the storage area for the record
  2131.                         data.
  2132.  
  2133.  
  2134. Description
  2135.  
  2136.         The DbRecordGetPrev function retrieves the previous record by the
  2137.         key field passed.  After this call, the currency for this record
  2138.         type is set to the record retrieved.
  2139.  
  2140.  
  2141. Return Value
  2142.  
  2143.         A 0 is returned if no error occurred.  Otherwise the return code
  2144.         can be E_DOS, E_NORECNAME, E_NOFLDNAME, E_NOTAKEY, E_NOTFOUND,
  2145.         E_NOCURRENT, or E_NOPREV.  See the 'Error Messages' section for
  2146.         more detail on these values.
  2147.  
  2148.  
  2149. Example
  2150.  
  2151.         #include "dbmgr.h"
  2152.  
  2153.         void Function()
  2154.             {
  2155.             INT status;
  2156.             CLIENT client;
  2157.  
  2158.             /* Get the previous record sorted by client number*/
  2159.             if( status = DbRecordGetPrev( "client", "clientnbr", &client))
  2160.                 {
  2161.                 /* Record not retrieved */
  2162.                 }
  2163.             }
  2164.  
  2165.  
  2166. DbRecordUpdate
  2167. --------------
  2168.  
  2169. Summary
  2170.  
  2171.         INT DbRecordUpdate( CHAR *pRecName, VOID *pData)
  2172.  
  2173.  
  2174. Parameters
  2175.  
  2176.         pRecName    CHAR *  Pointer to the record name.
  2177.  
  2178.         pData            VOID *  Pointer to the updated record data.
  2179.  
  2180.  
  2181. Description
  2182.  
  2183.         The DbRecordUpdate function updates a database record.  The record
  2184.         to be updated must be current.  For more on currency, see the
  2185.         Database Currency section in this manual.
  2186.  
  2187.  
  2188. Return Value
  2189.  
  2190.         A 0 is returned if no error occurred.  Otherwise the return code
  2191.         can be E_DOS, E_NORECNAME, or E_NOCURRENT.  See the 'Error Messages'
  2192.         section for more detail on these values.
  2193.  
  2194.  
  2195. Example
  2196.  
  2197.         #include "dbmgr.h"
  2198.  
  2199.         void Function()
  2200.             {
  2201.             INT status;
  2202.             CLIENT client;
  2203.  
  2204.             /* Get the first record */
  2205.             if( status = DbRecordGetFirst( "client", "clientnbr", &client))
  2206.                 {
  2207.                 /* Record not retrieved */
  2208.                 }
  2209.  
  2210.             /* Modify input logic goes here... */
  2211.  
  2212.             /* Update the record */
  2213.             if( status = DbRecordUpdate( "client", &client))
  2214.                 {
  2215.                 /* Error updating record */
  2216.                 }
  2217.             }
  2218.  
  2219.  
  2220. DbRecordUpdCurrency
  2221. -------------------
  2222.  
  2223. Summary
  2224.  
  2225.         INT DbRecordUpdCurrency( CHAR *pRecName, VOID *pData)
  2226.  
  2227.  
  2228. Parameters
  2229.  
  2230.         pRecName    CHAR *  Pointer to the record name.
  2231.  
  2232.         pData            VOID *  Pointer to the storage area for the currency
  2233.                         information.  
  2234.  
  2235.  
  2236. Description
  2237.  
  2238.         The DbRecordUpdCurrency function updates the currency for a
  2239.         specific record type.  For more on currency, see the Database
  2240.         Currency section in this manual.
  2241.  
  2242.  
  2243. Return Value
  2244.  
  2245.         A 0 is returned if no error occurred.  Otherwise the return code
  2246.         can be E_DOS or E_NORECNAME.  See the 'Error Messages' section for
  2247.         more detail on these values.
  2248.  
  2249.  
  2250. Example
  2251.  
  2252.         #include "dbmgr.h"
  2253.  
  2254.         void Function()
  2255.             {
  2256.             INT status;
  2257.             struct currency_index currency;
  2258.  
  2259.             /* Get the currency for the client record */
  2260.             if( status = DbRecordGetCurrency( "client", ¤cy))
  2261.                 {
  2262.                 /* Error retrieving currency */
  2263.                 }
  2264.  
  2265.             /* Other processing goes here... */
  2266.  
  2267.             /* Restore the currency for the client record */
  2268.             if( status = DbRecordUpdCurrency( "client", ¤cy))
  2269.                 {
  2270.                 /* Error updating currency */
  2271.                 }
  2272.             }
  2273.  
  2274.  
  2275. DbSetAdd
  2276. --------
  2277.  
  2278. Summary
  2279.  
  2280.         INT DbSetAdd( CHAR *pOwnerName, CHAR *pMemberName)
  2281.  
  2282.  
  2283. Parameters
  2284.  
  2285.         pOwnerName    CHAR *  Pointer to the owner record name.
  2286.  
  2287.         pMemberName    CHAR *  Pointer to the member record name.
  2288.  
  2289.  
  2290. Description
  2291.  
  2292.         The DbSetAdd function makes a set connection between two records.
  2293.         Both records must have currency before making the call.
  2294.  
  2295.  
  2296. Return Value
  2297.  
  2298.         A 0 is returned if no error occurred.  Otherwise the return code
  2299.         can be E_DOS,  E_NORECNAME, E_INVALIDSET, or E_NOCURRENT.  See the
  2300.         'Error Messages' section for more detail on these values.
  2301.  
  2302.  
  2303. Example
  2304.  
  2305.         #include "dbmgr.h"
  2306.  
  2307.         void Function()
  2308.             {
  2309.             INT status;
  2310.  
  2311.             /* Add an client record */
  2312.             /* Assuming 'sclient' is global and structure prefilled */
  2313.             if( status = DbRecordAdd( "client", &sclient))
  2314.                 {
  2315.                 /* Error adding record */
  2316.                 }
  2317.  
  2318.             /* Add an address record */
  2319.             /* Assuming 'saddress' is global and structure prefilled */
  2320.             if( status = DbRecordAdd( "address", &saddress))
  2321.                 {
  2322.                 /* Error adding record */
  2323.                 }
  2324.  
  2325.             /* Make a set connection between records */
  2326.             /* After this call, the 'client' record is the owner of the */
  2327.             /* 'address' record */
  2328.             /* The 'address' record is a member of the 'client' record */
  2329.             if( status = DbSetAdd( "client", "address"))
  2330.                 {
  2331.                 /* Error making set connection */
  2332.                 }
  2333.             }
  2334.  
  2335.  
  2336. DbSetDelete
  2337. -----------
  2338.  
  2339. Summary
  2340.  
  2341.         INT DbSetDelete( CHAR *pOwnerName, CHAR *pMemberName)
  2342.  
  2343.  
  2344. Parameters
  2345.  
  2346.         pOwnerName    CHAR *  Pointer to the owner record name.
  2347.  
  2348.         pMemberName    CHAR *  Pointer to the member record name.
  2349.  
  2350.  
  2351. Description
  2352.  
  2353.         The DbSetDelete function removes a set connection between two
  2354.         records.  Both records must have currency before making the call.
  2355.         This function does not delete either record, it only removes the
  2356.         connection between the two.
  2357.  
  2358.  
  2359. Return Value
  2360.  
  2361.         A 0 is returned if no error occurred.  Otherwise the return code
  2362.         can be E_DOS, E_NORECNAME, E_INVALIDSET, or E_NOCURRENT.  See the
  2363.         'Error Messages' section for more detail on these values.
  2364.  
  2365.  
  2366. Example
  2367.  
  2368.         #include "dbmgr.h"
  2369.  
  2370.         void Function()
  2371.             {
  2372.             INT status;
  2373.             LONG clientnbr = 1000L;
  2374.  
  2375.             /* Set the currency to client record #1000 */
  2376.             if( status = DbRecordFindByKey( "client", "clientnbr",
  2377.                 &clientnbr))
  2378.                 {
  2379.                 /* Record not found */
  2380.                 }
  2381.  
  2382.             /* Set the currency for the address record to the first */
  2383.             /* member of the client record */
  2384.             if( status = DbSetFindFirst( "client", "address"))
  2385.                 {
  2386.                 /* First member not found */
  2387.                 }
  2388.  
  2389.             /* Delete the owner/member set connection */
  2390.             if( status = DbSetDelete( "client", "address"))
  2391.                 {
  2392.                 /* Error deleting record */
  2393.                 }
  2394.             }
  2395.  
  2396.  
  2397. DbSetFindFirst
  2398. --------------
  2399.  
  2400. Summary
  2401.  
  2402.         INT DbSetFindFirst( CHAR *pOwnerName, CHAR *pMemberName)
  2403.  
  2404. Parameters
  2405.  
  2406.         pOwnerName    CHAR *  Pointer to the owner record name.
  2407.  
  2408.         pMemberName    CHAR *  Pointer to the member record name.
  2409.  
  2410.  
  2411. Description
  2412.  
  2413.         The DbSetFindFirst function sets the database currency for the
  2414.         member record to the first member in the owner/member set relation.
  2415.         The owner record must have currency before this call.  For more on
  2416.         currency, see the Database Currency section in this manual.
  2417.  
  2418.  
  2419. Return Value
  2420.  
  2421.         A 0 is returned if no error occurred.  Otherwise the return code
  2422.         can be E_DOS, E_NORECNAME, E_INVALIDSET, E_NOCURRENT, or E_NOTFOUND.
  2423.         See the 'Error Messages' section for more detail on these values.
  2424.  
  2425.  
  2426. Example
  2427.  
  2428.         #include "dbmgr.h"
  2429.  
  2430.         void Function()
  2431.             {
  2432.             INT status;
  2433.             LONG clientnbr = 1000L;
  2434.  
  2435.             /* Set the currency to client record #1000 */
  2436.             if( status = DbRecordFindByKey( "client", "clientnbr",
  2437.                 &clientnbr))
  2438.                 {
  2439.                 /* Record not found */
  2440.                 }
  2441.  
  2442.             /* Set the currency for the address record to the first */
  2443.             /* member of the client record */
  2444.             if( status = DbSetFindFirst( "client", "address"))
  2445.                 {
  2446.                 /* First member not found */
  2447.                 }
  2448.             }
  2449.  
  2450.  
  2451. DbSetFindLast
  2452. -------------
  2453.  
  2454. Summary
  2455.  
  2456.         INT DbSetFindLast( CHAR *pOwnerName, CHAR *pMemberName)
  2457.  
  2458.  
  2459. Parameters
  2460.  
  2461.         pOwnerName    CHAR *  Pointer to the owner record name.
  2462.  
  2463.         pMemberName    CHAR *  Pointer to the member record name.
  2464.  
  2465.  
  2466. Description
  2467.  
  2468.         The DbSetFindLast function sets the database currency for the
  2469.         member record to the last member in the owner/member set relation.
  2470.         The owner record must have currency before this call.  For more on
  2471.         currency, see the Database Currency section in this manual.
  2472.  
  2473.  
  2474. Return Value
  2475.  
  2476.         A 0 is returned if no error occurred.  Otherwise the return code
  2477.         can be E_DOS, E_NORECNAME, E_INVALIDSET, E_NOCURRENT, or E_NOTFOUND.
  2478.         See the 'Error Messages' section for more detail on these values.
  2479.  
  2480.  
  2481. Example
  2482.  
  2483.         #include "dbmgr.h"
  2484.  
  2485.         void Function()
  2486.             {
  2487.             INT status;
  2488.             LONG clientnbr = 1000L;
  2489.  
  2490.             /* Set the currency to client record #1000 */
  2491.             if( status = DbRecordFindByKey( "client", "clientnbr",
  2492.                 &clientnbr))
  2493.                 {
  2494.                 /* Record not found */
  2495.                 }
  2496.  
  2497.             /* Set the currency for the address record to the last */
  2498.             /* member of the client record */
  2499.             if( status = DbSetFindLast( "client", "address"))
  2500.                 {
  2501.                 /* Last member not found */
  2502.                 }
  2503.             }
  2504.  
  2505.  
  2506. DbSetFindNext
  2507. -------------
  2508.  
  2509. Summary
  2510.  
  2511.         INT DbSetFindNext( CHAR *pOwnerName, CHAR *pMemberName)
  2512.  
  2513.  
  2514. Parameters
  2515.  
  2516.         pOwnerName    CHAR *  Pointer to the owner record name.
  2517.  
  2518.         pMemberName    CHAR *  Pointer to the member record name.
  2519.  
  2520.  
  2521. Description
  2522.  
  2523.         The DbSetFindNext function sets the database currency for the
  2524.         member record to the next member in the owner/member set relation.
  2525.         Both owner and member records must have currency before this call.
  2526.         For more on currency, see the Database Currency section in this
  2527.         manual.
  2528.  
  2529.  
  2530. Return Value
  2531.  
  2532.         A 0 is returned if no error occurred.  Otherwise the return code
  2533.         can be E_DOS, E_NORECNAME, E_INVALIDSET, E_NOCURRENT, or E_NONEXT.
  2534.         See the 'Error Messages' section for more detail on these values.
  2535.  
  2536.  
  2537. Example
  2538.  
  2539.         #include "dbmgr.h"
  2540.  
  2541.         void Function()
  2542.             {
  2543.             INT status;
  2544.             LONG clientnbr = 1000L;
  2545.  
  2546.             /* Set the currency to client record #1000 */
  2547.             if( status = DbRecordFindByKey( "client", "clientnbr",
  2548.                 &clientnbr))
  2549.                 {
  2550.                 /* Record not found */
  2551.                 }
  2552.  
  2553.             /* Set the currency for the address record to the first */
  2554.             /* member of the client record */
  2555.             if( status = DbSetFindFirst( "client", "address"))
  2556.                 {
  2557.                 /* First member not found */
  2558.                 }
  2559.  
  2560.             /* Set the currency for the address record to the next member */
  2561.             /* of the client record */
  2562.             if( status = DbSetFindNext( "client", "address"))
  2563.                 {
  2564.                 /* Next member not found */
  2565.                 }
  2566.             }
  2567.  
  2568.  
  2569. DbSetFindPrev
  2570. -------------
  2571.  
  2572. Summary
  2573.  
  2574.         INT DbSetFindPrev( CHAR *pOwnerName, CHAR *pMemberName)
  2575.  
  2576.  
  2577. Parameters
  2578.  
  2579.         pOwnerName    CHAR *  Pointer to the owner record name.
  2580.  
  2581.         pMemberName    CHAR *  Pointer to the member record name.
  2582.  
  2583.  
  2584. Description
  2585.  
  2586.         The DbSetFindPrev function sets the database currency for the
  2587.         member record to the previous member in the owner/member set
  2588.         relation.  Both owner and member records must have currency
  2589.         before this call.  For more on currency, see the Database Currency
  2590.         section in this manual.
  2591.  
  2592.  
  2593. Return Value
  2594.  
  2595.         A 0 is returned if no error occurred.  Otherwise the return code
  2596.         can be E_DOS, E_NORECNAME, E_INVALIDSET, E_NOCURRENT, or E_NOPREV.
  2597.         See the 'Error Messages' section for more detail on these values.
  2598.  
  2599.  
  2600. Example
  2601.  
  2602.         #include "dbmgr.h"
  2603.  
  2604.         void Function()
  2605.             {
  2606.             INT status;
  2607.             LONG clientnbr = 1000L;
  2608.  
  2609.             /* Set the currency to client record #1000 */
  2610.             if( status = DbRecordFindByKey( "client", "clientnbr",
  2611.                 &clientnbr))
  2612.                 {
  2613.                 /* Record not found */
  2614.                 }
  2615.  
  2616.             /* Set the currency for the address record to the last */
  2617.             /* member of the client record */
  2618.             if( status = DbSetFindLast( "client", "address"))
  2619.                 {
  2620.                 /* Last member not found */
  2621.                 }
  2622.  
  2623.             /* Set the currency for the address record to the previous */
  2624.             /* member of the client record */
  2625.             if( status = DbSetFindPrev( "client", "address"))
  2626.                 {
  2627.                 /* Previous member not found */
  2628.                 }
  2629.             }
  2630.  
  2631.  
  2632. DbSetGetFirst
  2633. -------------
  2634.  
  2635. Summary
  2636.  
  2637.         INT DbSetGetFirst( CHAR *pOwnerName, CHAR *pMemberName,
  2638.                 VOID *pTarget)
  2639.  
  2640.  
  2641. Parameters
  2642.  
  2643.         pOwnerName    CHAR *  Pointer to the owner record name.
  2644.  
  2645.         pMemberName    CHAR *  Pointer to the member record name.
  2646.  
  2647.         pTarget            VOID *  Pointer to the storage area for the record
  2648.                         data.
  2649.  
  2650.  
  2651. Description
  2652.  
  2653.         The DbSetGetFirst function retrieves the first member of an
  2654.         owner/member set relation.  The owner record must have currency
  2655.         before this call.  For more on currency, see the Database Currency
  2656.         section in this manual.
  2657.  
  2658.  
  2659. Return Value
  2660.  
  2661.         A 0 is returned if no error occurred.  Otherwise the return code
  2662.         can be E_DOS, E_NORECNAME, E_INVALIDSET, E_NOCURRENT, or E_NOTFOUND.
  2663.         See the 'Error Messages' section for more detail on these values.
  2664.  
  2665.  
  2666. Example
  2667.  
  2668.         #include "dbmgr.h"
  2669.  
  2670.         void Function()
  2671.             {
  2672.             INT status;
  2673.             LONG clientnbr = 1000L;
  2674.             ADDRESS address;
  2675.  
  2676.             /* Set the currency to client record #1000 */
  2677.             if( status = DbRecordFindByKey( "client", "clientnbr",
  2678.                 &clientnbr))
  2679.                 {
  2680.                 /* Record not found */
  2681.                 }
  2682.  
  2683.             /* Get the first address record */
  2684.             if( status = DbSetGetFirst( "client", "address", &address))
  2685.                 {
  2686.                 /* First member not found */
  2687.                 }
  2688.             }
  2689.  
  2690.  
  2691. DbSetGetLast
  2692. ------------
  2693.  
  2694. Summary
  2695.  
  2696.         INT DbSetGetLast( CHAR *pOwnerName, CHAR *pMemberName, VOID *pTarget)
  2697.  
  2698.  
  2699. Parameters
  2700.  
  2701.         pOwnerName    CHAR *  Pointer to the owner record name.
  2702.  
  2703.         pMemberName    CHAR *  Pointer to the member record name.
  2704.  
  2705.         pTarget            VOID *  Pointer to the storage area for the record
  2706.                         data.
  2707.  
  2708.  
  2709. Description
  2710.  
  2711.         The DbSetGetLast function retrieves the last member of an
  2712.         owner/member set relation.  The owner record must have currency
  2713.         before this call.  For more on currency, see the Database Currency
  2714.         section in this manual.
  2715.  
  2716.  
  2717. Return Value
  2718.  
  2719.         A 0 is returned if no error occurred.  Otherwise the return code
  2720.         can be E_DOS, E_NORECNAME, E_INVALIDSET, E_NOCURRENT, or E_NOTFOUND.
  2721.         See the 'Error Messages' section for more detail on these values.
  2722.  
  2723.  
  2724. Example
  2725.  
  2726.         #include "dbmgr.h"
  2727.  
  2728.         void Function()
  2729.             {
  2730.             INT status;
  2731.             LONG clientnbr = 1000L;
  2732.             ADDRESS address;
  2733.  
  2734.             /* Set the currency to client record #1000 */
  2735.             if( status = DbRecordFindByKey( "client", "clientnbr",
  2736.                 &clientnbr))
  2737.                 {
  2738.                 /* Record not found */
  2739.                 }
  2740.  
  2741.             /* Get the last address record */
  2742.             if( status = DbSetGetLast( "client", "address", &address))
  2743.                 {
  2744.                 /* Last member not found */
  2745.                 }
  2746.             }
  2747.  
  2748.  
  2749. DbSetGetNext
  2750. ------------
  2751.  
  2752. Summary
  2753.  
  2754.         INT DbSetGetNext( CHAR *pOwnerName, CHAR *pMemberName, VOID *pTarget)
  2755.  
  2756.  
  2757. Parameters
  2758.  
  2759.         pOwnerName    CHAR *  Pointer to the owner record name.
  2760.  
  2761.         pMemberName    CHAR *  Pointer to the member record name.
  2762.  
  2763.         pTarget            VOID *  Pointer to the storage area for the record
  2764.                         data.
  2765.  
  2766.  
  2767. Description
  2768.  
  2769.         The DbSetGetNext function retrieves the next member of an
  2770.         owner/member set relation.  Both owner and member records must
  2771.         have currency before this call.  For more on currency, see the
  2772.         Database Currency section in this manual.
  2773.  
  2774.  
  2775. Return Value
  2776.  
  2777.         A 0 is returned if no error occurred.  Otherwise the return code
  2778.         can be E_DOS, E_NORECNAME, E_INVALIDSET, E_NOCURRENT, or E_NONEXT.
  2779.         See the 'Error Messages' section for more detail on these values.
  2780.  
  2781.  
  2782. Example
  2783.  
  2784.         #include "dbmgr.h"
  2785.  
  2786.         void Function()
  2787.             {
  2788.             INT status;
  2789.             LONG clientnbr = 1000L;
  2790.             ADDRESS address;
  2791.  
  2792.             /* Set the currency to client record #1000 */
  2793.             if( status = DbRecordFindByKey( "client", "clientnbr",
  2794.                 &clientnbr))
  2795.                 {
  2796.                 /* Record not found */
  2797.                 }
  2798.  
  2799.             /* Get the first address record */
  2800.             if( status = DbSetGetFirst( "client", "address", &address))
  2801.                 {
  2802.                 /* First member not found */
  2803.                 }
  2804.  
  2805.             /* Get the next address record */
  2806.             if( status = DbSetGetNext( "client", "address", &address))
  2807.                 {
  2808.                 /* Next member not found */
  2809.                 }
  2810.             }
  2811.  
  2812.  
  2813. DbSetGetOwner
  2814. -------------
  2815.  
  2816. Summary
  2817.  
  2818.         INT DbSetGetOwner( CHAR *pOwnerName, CHAR *pMemberName,
  2819.             VOID *pTarget)
  2820.  
  2821.  
  2822. Parameters
  2823.  
  2824.         pOwnerName    CHAR *  Pointer to the owner record name.
  2825.  
  2826.         pMemberName    CHAR *  Pointer to the member record name.
  2827.  
  2828.         pTarget            VOID *  Pointer to the storage area for the record
  2829.                         data.
  2830.  
  2831.  
  2832. Description
  2833.  
  2834.         The DbSetGetOwner function retrieves the owner record of a member
  2835.         record set relation.  The member record must have currency before
  2836.         this call.  For more on currency, see the Database Currency section
  2837.         in this manual.
  2838.  
  2839.  
  2840. Return Value
  2841.  
  2842.         A 0 is returned if no error occurred.  Otherwise the return code
  2843.         can be E_DOS, E_NORECNAME, E_INVALIDSET, E_NOCURRENT, or E_NOOWNER.
  2844.         See the 'Error Messages' section for more detail on these values.
  2845.  
  2846.  
  2847. Example
  2848.  
  2849.         #include "dbmgr.h"
  2850.  
  2851.         void Function()
  2852.             {
  2853.             INT status;
  2854.             CLIENT client;
  2855.  
  2856.             /* Set the currency to the first invoice record */
  2857.             if( status = DbRecordFindFirst( "invoice", "invoicenbr"))
  2858.                 {
  2859.                 /* Invoice not found */
  2860.                 }
  2861.  
  2862.             /* Get the client record for this invoice */
  2863.             if( status = DbSetGetOwner( "client", "invoice", &client))
  2864.                 {
  2865.                 /* Client record not found */
  2866.                 }
  2867.             }
  2868.  
  2869.  
  2870. DbSetGetPrev
  2871. ------------
  2872.  
  2873. Summary
  2874.  
  2875.         INT DbSetGetPrev( CHAR *pOwnerName, CHAR *pMemberName, VOID *pTarget)
  2876.  
  2877.  
  2878. Parameters
  2879.  
  2880.         pOwnerName    CHAR *  Pointer to the owner record name.
  2881.  
  2882.         pMemberName    CHAR *  Pointer to the member record name.
  2883.  
  2884.         pTarget            VOID *  Pointer to the storage area for the record
  2885.                         data.
  2886.  
  2887.  
  2888. Description
  2889.  
  2890.         The DbSetGetPrev function retrieves the previous member of an
  2891.         owner/member set relation.  Both owner and member records must
  2892.         have currency before this call.  For more on currency, see the
  2893.         Database Currency section in this manual.
  2894.  
  2895.  
  2896. Return Value
  2897.  
  2898.         A 0 is returned if no error occurred.  Otherwise the return code
  2899.         can be E_DOS, E_NORECNAME, E_INVALIDSET, E_NOCURRENT, or E_NOPREV.
  2900.         See the 'Error Messages' section for more detail on these values.
  2901.  
  2902.  
  2903. Example
  2904.  
  2905.         #include "dbmgr.h"
  2906.  
  2907.         void Function()
  2908.             {
  2909.             INT status;
  2910.             LONG clientnbr = 1000L;
  2911.             ADDRESS address;
  2912.  
  2913.             /* Set the currency to client record #1000 */
  2914.             if( status = DbRecordFindByKey( "client", "clientnbr",
  2915.                 &clientnbr))
  2916.                 {
  2917.                 /* Record not found */
  2918.                 }
  2919.  
  2920.             /* Get the last address record */
  2921.             if( status = DbSetGetLast( "client", "address", &address))
  2922.                 {
  2923.                 /* Last member not found */
  2924.                 }
  2925.  
  2926.             /* Get the previous address record */
  2927.             if( status = DbSetGetPrev( "client", "address", &address))
  2928.                 {
  2929.                 /* Previous member not found */
  2930.                 }
  2931.             }
  2932.  
  2933.  
  2934. ERROR MESSAGES
  2935.  
  2936.         This section describes error messages that you may encounter when
  2937.         developing a program using CDB.
  2938.  
  2939.  
  2940. CDB Run-Time Error Messages
  2941.  
  2942.         The CDB C-API function calls return an INT value indicating the
  2943.         success or failure of a particular database call.  A 0 is returned
  2944.         if the function was a success.  A non-zero value is returned if an
  2945.         error occured.
  2946.  
  2947.         The following list displays the possible error codes that can be
  2948.         returned and a brief explanation of each.
  2949.  
  2950.  
  2951.         Error Code        Description
  2952.  
  2953.         E_TESTDRIVE        You are using a 'Test Drive' version of CDB.
  2954.                                 The 'Test Drive' version limits the number
  2955.                                 of records that can be added to a database
  2956.                                 to 50.
  2957.  
  2958.         E_INVALIDCASE            Contact Daytris technical support.  An
  2959.                                 internal switch statement does not contain
  2960.                                 a valid case.  You should never see this
  2961.                                 error code.
  2962.  
  2963.         E_DOS                An MS-DOS error has occured.  The global
  2964.                                 'errno' value contains the specific DOS
  2965.                                 error number.  See ERRNO.H and/or the
  2966.                                 Microsoft C documentation for more
  2967.                                 information.
  2968.  
  2969.         E_NORECNAME            The record name passed, pRecName, is not a
  2970.                                 valid record type.
  2971.  
  2972.         E_NOFLDNAME            The field name passed, pFldName, is not a
  2973.                                 valid field for the record.
  2974.  
  2975.         E_INVALIDSET            The owner and member names passed to the
  2976.                                 function do not have a set relationship
  2977.                                 between the two.  To create a set
  2978.                                 relatiionship between two records, use the
  2979.                                 CONNECT keyword in the DDL file.
  2980.  
  2981.         E_NOTAKEY               The field name passed to the function is
  2982.                                 not a key field in the record.  Use the KEY
  2983.                                 keyword in the DDL file to define key
  2984.                                 fields.
  2985.  
  2986.         E_NOTFOUND                The record was not found.
  2987.  
  2988.  
  2989.         E_NEXTGUESS        The record was not found, but the next
  2990.                                 closest match to the key value passed was
  2991.                                 found.  If a DbRecordFindByKey call was
  2992.                                 made, currency is set to this 'next guess'
  2993.                                 record.  If a DbRecordGetByKey call was
  2994.                                 made, the 'next guess' record is returned.
  2995.  
  2996.         E_NOCURRENT            There is no current record for the record
  2997.                                 name specified.  e.g.  This error value
  2998.                                 will be returned if a DbRecordGetNext call
  2999.                                 is made before the record requested has
  3000.                                 currency.  One way to set currency in this
  3001.                                 case would be to make a DbRecordFindFirst
  3002.                                 call.  There are a number of other cases
  3003.                                 where this error code could be returned.
  3004.  
  3005.         E_NONEXT        The next record was not found.  e.g. 
  3006.                                 DbRecordGetNext(...).
  3007.  
  3008.         E_NOPREV        The previous record was not found.  e.g. 
  3009.                                 DbRecordGetPrevious(...).
  3010.  
  3011.         E_NOOWNER        This error can only occur with a
  3012.                                 DbSetGetOwner call.  If an owner record is
  3013.                                 not found, this value is returned.
  3014.  
  3015.  
  3016. DDLP Error Messages
  3017.  
  3018.         The following lists contain a description of error and warning
  3019.         messages that may be encountered during the execution of the Data
  3020.         Definition Language Parse utility (DDLP.EXE):
  3021.  
  3022.         Error Number    Description
  3023.  
  3024.         100        Unexpected end of file reached.
  3025.         101        Unexpected token.  DDLP breaks the DDL file into
  3026.                         tokens.  A token can be a bracket, keyword,
  3027.                         semicolon, variable, constant, etc.  It combines the
  3028.                         tokens and matches them against predefined patterns.
  3029.                         If a pattern has no match, this error is returned.
  3030.         102        Expecting semicolon.
  3031.         103        Expecting "struct" keyword.  DDLP is expecting a 
  3032.                         structure definition to begin.
  3033.         104        Expecting identifier.  An identifer can be a
  3034.                         structure name or field name.
  3035.         105        Expecting '{'.  Expecting a left brace.
  3036.         106        Constant too big.  A constant is a number.  The 
  3037.                         maximum constant size allowed is 10 digits.
  3038.         107        Structure already defined.
  3039.         108        Invalid constant.  The interpreted value of the 
  3040.                         constant is zero.
  3041.         109        Maximum size of a constant is 65535.
  3042.         110        Maximum size of a field is 65535.
  3043.         111        Maximum size of a record is 65535.
  3044.         112        Connection already made to 'record name'.  You 
  3045.                         cannot to the same record more than once.
  3046.         113        Record does not exist.  This error will occur when 
  3047.                         you try to CONNECT to a record that is not defined 
  3048.                         within the DDL file.
  3049.         114        Cannot connect structure to itself.
  3050.         115        Connect key field not found.  If you are ordering
  3051.                         the sets using the 'CONNECT record_name KEY
  3052.                         key_field_name' convention, the key_field_name is
  3053.                         not found within the record_name structure
  3054.                         definition in the DDL file.
  3055.  
  3056.         Warning Number    Description
  3057.  
  3058.         100        "prefix" not defined, assuming "test".  The PREFIX
  3059.                         keyword was not used to define the prefix used to
  3060.                         derive database file names.  A "test" prefix is
  3061.                         used as a default.
  3062.         101        Prefix too long, truncating to 'identifier'.  The
  3063.                         maximum length of a PREFIX is 5 characters.
  3064.         102        Identifier too long.  The maximum length of an
  3065.                         identifier is 31 characters.  Extra characters will
  3066.                         be truncated.
  3067.